c# - 从 MVC4 中的 View 将 2 个不同模型传递给 Controller ​​的适当方法是什么

标签 c# asp.net-mvc asp.net-mvc-3 asp.net-mvc-4

我正在将 MVC4 与 SimpleMembership 结合使用。 MVC 已经设置了我的 UserProfile 表,并且我已经修改了注册 View 以适应我的布局。一切都很好,直到我确定我想包含一些来 self 的用户的最适合另一个已经存在的模型的上下文的附加信息。

通常,我将多个模型从我的 View 传递到 Controller 的方法是使用元组。从历史上看,这对我来说效果很好,直到现在我才遇到任何真正的问题。

我的注册表格是这样的:

@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)                             
   }    

我的Controller的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);
    }

每当我在单击“提交”按钮后调试此代码时,我都会注意到返回到 Controller 的两个模型都是空的。包含的字段为 null、0 或空字符串,我不明白为什么。

为了增加这个谜团,如果我从 View 顶部删除元组并将其重新分配为单个模型:

@model MyNamespace.Models.RegisterModel

并将代码中的元组引用(例如 m.Item1.Property、m.Item2.Property)替换为 1 模型推断引用(m.Property 等);然后将从 TextBox 助手传入的数据适本地分配给模型,并在我调试代码时填充模型。

现在,我知道我可以简单地向 UserProfile 表添加一些其他字段并在我的模型中使用它们来完全减少元组,但是我在我的模式中复制数据,这不是一个理想的解决方案。请记住,虽然我在此处提供的示例代码仅包含第二个模型的 1 个元素,但实际上它会超过 1 个。

那么为什么在使用元组时模型没有被填充,是否有更合适的方法来解决这个问题?或者我不能在单个表单提交中混合模型数据???

最佳答案

首先,使用 Tuple 作为模型不是一个好的做法,因为它很难阅读代码。您应该为此编写页面自己的 View 模型。 对于此示例,例如:

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

它很容易实现,并且可以按照您的意愿工作。

但是如果你想在 View 上使用元组作为模型。

你应该得到你的帖子 Action

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

因为表单 html 将被创建为:

  <input name="Item1.ProfileName" />  

您可以看到,它会尝试发送默认模型绑定(bind)器不支持的 Item1.Profile 名称,以将其转换为您自己的类。它会期望一个元组或类似 :.

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

基本上就像 View 模型一样

关于c# - 从 MVC4 中的 View 将 2 个不同模型传递给 Controller ​​的适当方法是什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23875456/

相关文章:

c# - 从受信任的域中将成员添加到 AD 组

c# - 标签从右向左增长

asp.net-mvc - 如何在asp.net mvc 3中使用jquery和数据注释验证输入文件

c# - 在不丢失当前页面/过滤器的情况下刷新 MVC3/MVC4 WebGrid

c# - 从文件的根文件夹获取相对路径

jquery - 对隐藏字段执行验证

c# - 使用大 URL 查询进行路由

c# - 为什么 DateTime.Now.ToBinary() 返回与构造函数创建时不同的值

c# - 为什么使用硬编码字符串值正确呈现单选按钮?

asp.net-mvc - 如何在没有互联网的情况下在构建服务器/生产服务器上使用 NuGet 包?