asp.net - MVC 4 - 在局部 View 中使用不同的模型

标签 asp.net asp.net-mvc asp.net-mvc-4 model

请容忍我的菜鸟,我对 MVC 模式非常陌生。

我想做什么

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

我的问题

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

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

The model item passed into the dictionary is of type 'Applicense.Models.User', but this dictionary requires a model item of type 'Applicense.Models.ProfileModel'.



这是我对局部 View 的调用:
 @using (Html.BeginForm())
    {
        @Html.AntiForgeryToken()
        @Html.ValidationSummary()

        @Html.Partial("_ModifyProfileInfo")
    }

这是部分 View :
@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; }
    }

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

编辑:
我重新编写了反射(reflect) Nikola Mitev 答案的代码,但现在我遇到了另一个问题。这是我得到的错误:

Object reference not set to an instance of an object. (@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; }
    }

Controller :
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列到数据库中。

编辑 2:
我的 Profile 操作的 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);
            }
        }

最佳答案

处理这种情况的最佳方法是使用 viewModel 并将其传递给 Profile Controller ,viewModel 是您要传递给 View 的多个对象的包装类。

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

您的 Controller 应如下所示:
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>
}

关于asp.net - MVC 4 - 在局部 View 中使用不同的模型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17173204/

相关文章:

asp.net-mvc-4 - ASP.Net MVC + Web Api + AngularJs 中的页面重定向

c# - MS 图表控件 : Formatting Axis Labels

c# - Page_Load、Page_PreInit 和 Page_OnInit

c# - 0x800a1391 - JavaScript 运行时错误 : 'Edit_Button_Click' is undefined

asp.net - 在 Visual Studio 2010 中编辑 aspx/ascx 文件随机禁用?

javascript - JQuery DataTables 无法识别加载的数据

c# - 在 asp.net MVC 中以英国格式将日期时间从 View 传递到 Controller

asp.net-mvc - 所有请求均出现 HTTP 错误 401.2 - 未经授权的响应

css - 如何访问Area部分指定的MVC中的css资源?

entity-framework - 唯一字段 mvc 的客户端验证