29

私の初心者でご容赦ください。私はMVCパターンに非常に慣れていません。

私がやろうとしていること

サイトに登録ユーザーのプロフィール情報ページを作成しています。このページには、生年月日、電話番号、サブスクリプション ステータスなど、ユーザーに関するデータが一覧表示されます。また、ユーザーがパスワード、メールアドレス、個人情報を同じページで変更できるフォームが欲しいです。

私の問題

ユーザーのデータは、渡されたモデル変数を介してコントローラーから取得されます。

public ActionResult Profil()
        {
            var model = db.Users.First(e => e.UserName == WebSecurity.CurrentUserName);
            return View(model);
        }

私の見解では、出力は次のようになります。

<label>Phone number: </label>
            @if (Model.PhoneNumber != null)
                    {
                        @Model.PhoneNumber
                    }
                    else
                    {
                        <span class="red">You haven't set up your phone number yet. </span>
                    }

ユーザーが自分の情報を変更できるフォームは、別のモデル ProfileModel を使用します。基本的に、私の見解では 2 つのモデルを使用する必要があります。1 つは情報の出力用で、もう 1 つはデータの投稿用です。部分ビューを使用するとこれを達成できると思いましたが、次のエラーが発生します。

ディクショナリに渡されたモデル アイテムは「Applicense.Models.User」タイプですが、このディクショナリには「Applicense.Models.ProfileModel」タイプのモデル アイテムが必要です。

部分ビューへの呼び出しは次のようになります。

 @using (Html.BeginForm())
    {
        @Html.AntiForgeryToken()
        @Html.ValidationSummary()

        @Html.Partial("_ModifyProfileInfo")
    }

部分的なビューは次のとおりです。

@model Applicense.Models.ProfileModel
<ul>
    <li>
        @Html.LabelFor(m => m.Email)
        @Html.EditorFor(m => m.Email)
    </li>
    <li>
        @Html.LabelFor(m => m.ConfirmEmail)
        @Html.EditorFor(m => m.ConfirmEmail)
    </li>
    <input type="submit" value="Update e-mail" />
</ul>

最後に、私の ProfileModel は次のとおりです。

public class ProfileModel
    {
        [Required]
        [DataType(DataType.EmailAddress)]
        [Display(Name = "New e-mail address")]
        public string Email { get; set; }

        [DataType(DataType.EmailAddress)]
        [Display(Name = "Confirm new e-mail address")]
        [Compare("Email", ErrorMessage = "The e-mail and it's confirmation field do not match.")]
        public string ConfirmEmail { get; set; }
    }

何か不足していますか?これを行う適切な方法は何ですか?

編集: Nikola Mitev の回答を反映してコードを作り直しましたが、別の問題が発生しました。エラーは次のとおりです。

オブジェクト参照がオブジェクト インスタンスに設定されていません。(@Model.UserObject.LastName)

これは、変更した電子メール アドレスの値を投稿しているときにのみ発生します。これが私のViewModel(ProfileModel.cs)です:

public class ProfileModel
    {
        public User UserObject { get; set; }

        [Required]
        [DataType(DataType.EmailAddress)]
        [Display(Name = "Új e-mail cím")]
        public string Email { get; set; }

        [DataType(DataType.EmailAddress)]
        [Display(Name = "Új e-mail cím megerősítése")]
        [Compare("Email", ErrorMessage = "A két e-mail cím nem egyezik.")]
        public string ConfirmEmail { get; set; }

        [DataType(DataType.EmailAddress)]
        [Display(Name= "E-mail cím")]
        public string ReferEmail { get; set; }
    }

コントローラ:

public ActionResult Profil()
        {
            var User = db.Users.First(e => e.UserName == WebSecurity.CurrentUserName);

            var ProfileViewModel = new ProfileModel
            {
                UserObject = User
            };

            return View(ProfileViewModel);
        }

そして最後に、これが私のuser.csモデルクラスです:

[Table("UserProfile")]
    public class User
    {
        [Key]
        [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
        public int UserId { get; set; }
        [Column("UserName")]
        public string UserName { get; set; }
        [Column("Email")]
        [Required]
        public string Email { get; set; }
        [Column("FirstName")]
        public string FirstName { get; set; }
        [Column("LastName")]
        public string LastName { get; set; }
        [Column("PhoneNumber")]
        public string PhoneNumber { get; set; }
... You get the idea of the rest...

requiredモデルが各列のデータをデータベースに入れようとしているために起こっていると思います。

Edit2: 私のプロファイル アクションの httppost メソッド:

[HttpPost]
        [Authorize]
        [ValidateAntiForgeryToken]
        public ActionResult Profil(ProfileModel model)
        {
            if (ModelState.IsValid)
            {
//insert into database
                return Content("everything's good");
            }
            else
            {
//outputs form errors
                return View(model);
            }
        }
4

4 に答える 4

13

@Html.Partialコントローラーで定義されているように送信できるようにするオーバーロードがありViewDataます-これは、私が通常部分ビューに使用する方法です。コントローラーで として定義ViewData["mypartialdata"]ViewDataDictionaryます。次に、あなたの見解で

@Html.Partial("_ModifyProfileInfo",ViewData["mypartialdata"])
于 2013-06-18T15:45:30.537 に答える
1

[HttpPost]プロファイル関数で、が false の場合、modelstate.isvalid編集ビューを返しますが、pmViewModelagain を定義する必要があります。そうしないと、部分ビューに表示するオブジェクトがありません。以下を使用してみて、どうなるか教えてください

[HttpPost]
[Authorize]
[ValidateAntiForgeryToken]
public ActionResult Profil(ProfileModel model)
{
    if (ModelState.IsValid)
    {
        //insert into database
        return Content("everything's good");
    }
    else
    {
        //outputs form errors
        var pmViewModel = new ProfileUserViewModel  
        {
            ProfileModelObject = profileModel,
            UserModelObject = userModel
        };

        return View(model);
    }
}
于 2013-06-19T11:42:58.953 に答える