本文介绍了MVC 4 - 在局部视图中使用不同的模型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请忍受我的noobness,我对 MVC 模式非常陌生.

Please bear with my noobness, I'm super new to the MVC pattern.

我想做什么

我正在为我网站上的注册用户建立个人资料信息页面.此页面将列出有关用户的数据,例如出生日期、电话号码、订阅状态等.您明白了.我还想要一个表单,让用户可以在同一页面上更改他们的密码、电子邮件地址、个人信息.

I am building a profile information page for registered users on my site. This page would list data about the user, such as date of birth, telephone number, subscription status, etc.. You get the idea. I would also like to have a form to let users change their password, email address, personal information on the same page.

我的问题

用户的数据通过传递的模型变量来自我的控制器:

The user's data comes from my controller via a passed model variable:

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

在我看来,输出是这样的:

The output looks like this in my view:

<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.所以基本上我需要使用两种模型,一种用于输出信息,一种用于发布数据.我认为使用局部视图可以实现这一点,但出现此错误:

The form in which the user could change his info would use another model, ProfileModel. So basiccaly I need to use two models in my view, one for outputting information and one for posting data. I thought that using a partial view I can achieve this, but I get this error:

传入字典的模型项是类型'Applicense.Models.User',但是这个字典需要一个模型项输入Applicense.Models.ProfileModel".

这是我对局部视图的调用:

Here's what my call to the partial view looks like:

 @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:

And finally here's my 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; }
    }

我错过了什么吗?这样做的正确方法是什么?

Am I missing something? What's the proper way to do this?

我重新编写了反映 Nikola Mitev 答案的代码,但现在我遇到了另一个问题.这是我得到的错误:

I remade my code reflecting Nikola Mitev's answer, but now I have another problem. Here's the error I get:

未将对象引用设置为对象的实例.(@Model.UserObject.LastName)

这仅在我发布更改后的电子邮件地址值时发生.这是我的 ViewModel (ProfileModel.cs):

This only occurs when I'm posting the changed e-mail address values. Here's my 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 模型类:

And finally here's my user.cs model class:

[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 列中的数据放入数据库中.

I'm thinking it's happening because the model is trying to put data in each required columns into the database.

编辑 2:我的Profil动作的httppost方法:

The httppost method of my Profil action:

[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);
            }
        }

推荐答案

处理这种情况的最好方法是使用 viewModel 并将其传递给 Profile 控制器,viewModel 是您要传递给视图的多个对象的包装类.

The best way to handle this situation is to use and pass viewModel to your Profile controller, viewModel is wrapper class for multiple objects that you want to pass to your view.

public class ProfileUserViewModel
{
   public ProfileModel ProfileModelObject {get; set;}
   public UserModel  UserModelObject {get; set;}
}

您的控制器应如下所示:

Your controller should look like:

public ActionResult Profil()
{
    var profileModel = db.Users.First(e => e.UserName == WebSecurity.CurrentUserName);
    var userModel = //fetch from db.

    var pmViewModel = new ProfileUserViewModel
                          {
                              ProfileModelObject = profileModel,
                              UserModelObject = userModel
                          };

   return View(pmViewModel);
}

最后是你的观点:

@model Applicense.Models.ProfileUserViewModel

<label>Phone number: </label>

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

这篇关于MVC 4 - 在局部视图中使用不同的模型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-05 11:57