简体   繁体   English

从MVC4中的视图将2个不同的模型传递到控制器的适当方法是什么

[英]Whats the Appropriate Method to pass 2 different Models to the Controller from a View in MVC4

I am using MVC4 with SimpleMembership. 我正在将MVC4与SimpleMembership一起使用。 MVC has setup my UserProfile table and I've modified the Registration View to accomodate my layout. MVC设置了我的UserProfile表,并且我修改了“注册视图”以适应我的布局。 Everything worked great until I determined that I wanted to include some additional information from my user that best fit within the context of another already existing Model. 一切工作都很好,直到我确定要包括来自用户的一些其他信息,这些信息最适合另一个已经存在的Model的上下文。

Typically my approach to passing more than one Model from my View to the Controller has been to employ Tuples. 通常,我将多个模型从我的视图传递到控制器的方法是采用元组。 Historically this has worked out great for me and I've never had any real issues until now. 从历史上看,这对我非常有用,到目前为止,我从未遇到过任何实际问题。

My Registration Form resembles this: 我的注册表类似于以下内容:

@model Tuple<MyNamespace.Models.RegisterModel,MyNamespace.Models.MembershipDetail>

@using (Html.BeginForm(new { ReturnUrl = ViewBag.ReturnUrl })) {
@Html.AntiForgeryToken()     
    <table style="border-collapse: collapse; border-spacing:0px; border-width:0px; margin: 0px; width:100px; padding: 0 0 0 0px; background-color:#2e2e2e;">
        <tr>
           <td>
              Profile Name
           </td>
           <td>
              @Html.TextBoxFor(m => m.Item2.ProfileName)
           </td>
        </tr> 
        <tr>
           <td>
              @Html.LabelFor(m => m.Item1.UserName)
           </td>
           <td>
              @Html.TextBoxFor(m => m.Item1.UserName)
           </td>
        </tr>
        <tr>
           <td>
              @Html.LabelFor(m => m.Item1.Password)
           </td>
           <td>
              @Html.PasswordFor(m => m.Item1.Password)
           </td>
        </tr>
        <tr>
           <td>
              @Html.LabelFor(m => m.Item1.ConfirmPassword)
           </td>
           <td>
              @Html.PasswordFor(m => m.Item1.ConfirmPassword)
           </td>
        </tr>                               
        <tr>
           <td>
              <button type="submit" id="btnSubmitForm" value="Register">Register</button>
           </td>
        </tr>
     </table>
     @Html.Partial("_ValidationSummary",ViewData.ModelState)                             
   }    

The Register Method of my Controller is similar to this: 我的控制器的Register方法类似于以下内容:

    [HttpPost]
    [AllowAnonymous]
    [ValidateAntiForgeryToken]
    public ActionResult Register(RegisterModel model, MembershipDetail member)
    {
        if (ModelState.IsValid)
        {
            try
             {
                // Do something with the data
             }
            catch(MembershipCreateUserException e)
            {
               ModelState.AddModelError("",ErrorCodeToString(e.StatusCode));
            }
        }
        return View(model);
    }

Whenever I debug this code after the click of the Submit button, I note that both Models returned to the controller are empty. 单击“提交”按钮后,只要调试该代码,我都会注意到返回到控制器的两个模型都是空的。 The contained fields are either null, 0 or Empty Strings and I cannot figure out why. 包含的字段为null,0或Empty Strings,我不知道为什么。

To add to this mystery, if I remove the tuple from the top of the view and re-assign it as a single Model as such: 为了增加这个奥秘,如果我从视图顶部删除元组并将其重新分配为单个Model,如下所示:

@model MyNamespace.Models.RegisterModel

And replace the tuple references from the code (egmItem1.Property, m.Item2.Property) with the 1 Model inferred reference (m.Property and etc); 并用1模型推断的引用(m.Property等)替换代码中的元组引用(例如,egmItem1.Property,m.Item2.Property); then the data passed in from the TextBox helpers is appropriately assigned to the model and the model is populated when I debug the code. 然后将从TextBox帮助器传入的数据分配给模型,并在调试代码时填充模型。

Now, I know I could simply add a few other fields to the UserProfile table and use them in my Model to alleviate the Tuple altogether but then I am duplicating data in my schema which is not an ideal solution. 现在,我知道我可以简单地向UserProfile表中添加一些其他字段,并在我的模型中使用它们来完全缓解元组,但是随后我在模式中复制数据,这不是理想的解决方案。 And keeping in mind that though my sample code provided here only contains 1 element of the 2nd Model, it will actually be more than 1. 并且请记住,尽管此处提供的示例代码仅包含2nd Model的1个元素,但实际上将大于1。

So why don't the Models get populated when using the Tuple and is there a more appropriate way to go about solving this problem? 那么,为什么在使用元组时不填充模型,有没有更合适的方法来解决这个问题呢? Or can I not mix Model data on a single form submission??? 或者我不能在单个表单提交中混合使用模型数据吗???

First of all , it is not a good practice to use Tuple as model, because it is hard to read the code. 首先,将Tuple用作模型不是一个好习惯,因为很难读取代码。 You should write page's own viewmodels for that. 您应该为此编写页面自己的视图模型。 For this example like : 对于这样的示例:

 public class SomeViewModel{
         public RegisterModel RegisterModel { get; set;}
         public MembershipDetail MembershipDetail {get; set;}
 } 

it is easy to implement and will work as you want. 它易于实现,并且可以根据需要工作。

However if you want to use Tuples on the view as model. 但是,如果要在视图上使用元组作为模型。

You should get Your post action like 您应该像

   public ActionResult Register(Tuple<RegisterModel,MembershipDetail> model)
   {
     .... // do something..
   }

Because the form html will be created like : 因为表单html将像这样创建:

  <input name="Item1.ProfileName" />  

You can see , it will try to send Item1.Profile name which is not supported by default model binder to convert it to your own classes.. it will expect a Tuple or a class like :. 您会看到,它将尝试发送默认模型绑定程序不支持的Item1.Profile名称,以将其转换为您自己的类。.它期望使用元组或类似:的类。

   public class TheClass {
    public RegisterModel Item1 {get; set;}
    public MemberhipDetail Item2 {get; set;}
 }

which basically just like the viewmodel 基本上就像viewmodel

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM