Asp.net MVC4-在局部视图中使用不同的模型

Asp.net MVC4-在局部视图中使用不同的模型,asp.net,asp.net-mvc,asp.net-mvc-4,model,Asp.net,Asp.net Mvc,Asp.net Mvc 4,Model,请容忍我的无知,我是MVC模式的新手 我想做的事 我正在为我网站上的注册用户建立一个个人资料信息页面。此页面将列出有关用户的数据,如出生日期、电话号码、订阅状态等。。你明白了。我还希望有一个表单,允许用户在同一页面上更改密码、电子邮件地址、个人信息 我的问题 用户数据通过传递的模型变量来自我的控制器: public ActionResult Profil() { var model = db.Users.First(e => e.UserName =

请容忍我的无知,我是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>
                    }
以下是局部视图:

@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>
我错过什么了吗?正确的方法是什么

编辑: 我根据尼古拉·米捷夫的答案重新编写了代码,但现在我又遇到了另一个问题。下面是我得到的错误:

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

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

控制器:

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

            var ProfileViewModel = new ProfileModel
            {
                UserObject = User
            };

            return View(ProfileViewModel);
        }
最后是我的
user.cs
model类:

[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: 我的Profil操作的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);
            }
        }

有一个超负荷的
@Html.Partial
,它允许您发送控制器中定义的
视图数据
——这是我通常用于局部视图的方法。 在控制器中,将
ViewData[“mypartialdata”]
定义为
ViewDataDictionary
。那么在你看来,

@Html.Partial("_ModifyProfileInfo",ViewData["mypartialdata"])

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

public class ProfileUserViewModel
{
   public ProfileModel ProfileModelObject {get; set;}
   public UserModel  UserModelObject {get; set;}
}   
您的控制器应该如下所示:

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>
}
@model Applicense.Models.ProfileUserViewModel
电话号码:
@if(Model.ProfileModelObject.PhoneNumber!=null)
{
@Model.PhoneNumber
}
其他的
{
你还没有设置你的电话号码。
}

[HttpPost]
profil函数中,如果
modelstate.isvalid
为false,则返回编辑视图,但需要再次定义
pmViewModel
,否则,局部视图将不会显示对象。尝试使用下面的方法,让我们知道会发生什么

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

虽然我知道这个问题很久以前就被问过了,但是有些人可能仍然面临类似的问题。我用来传递或在页面上有多个视图模型的一个简单解决方案是使用ViewBag来保存第二个对象并在视图中引用它。参见下面的示例

在控制器中,执行以下操作:

Obj2 personalDets = new Obj2();
DbContext ctx = new DbContext();
var details = ctx.GetPersonalInformation;

foreach(var item in details) {
    personalDets.Password = item.Password;
    personalDets .EmailAddress = item.EmailAddress; 
}

ViewBag.PersonalInformation = personalDets;

然后,在您看来,这些属性将随时为您提供

谢谢,就像一个符咒一样有效!:)+我现在又犯了一个错误:(我编辑了这个问题以反映it@Tharline您试图获取的特定记录在LastName字段中是否有值?@Nicola Mitev是的,它有值。它输出值没有问题,例如,只有在我发布表单以更改电子邮件地址时才会发生错误。(虽然用户还没有更改LastName值的选项..谢谢!我实际上必须在返回任何视图之前放置pmViewModel才能使其工作。您声明了
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>
}
[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);
    }
}
Obj2 personalDets = new Obj2();
DbContext ctx = new DbContext();
var details = ctx.GetPersonalInformation;

foreach(var item in details) {
    personalDets.Password = item.Password;
    personalDets .EmailAddress = item.EmailAddress; 
}

ViewBag.PersonalInformation = personalDets;