我有这个视图模型:
public class MemberRegisterVM
{
public Users User { get; set; }
public Location Location { get; set; }
}
其中包含User
和Location
模型
用户:
public partial class Users : Persons
{
public Guid? UserRoleId { get; set; }
public string UserName { get; set; }
public string Password { get; set; }
public DateTime? RegisterDate { get; set; }
public DateTime ExpireDate { get; set; }
public bool IsLock { get; set; }
public string DigitalSignture { get; set; }
public Guid? BranchID { get; set; }
public int PersonType { get; set; }
public Guid Token { get; set; }
}
public partial class Users
{
public string NewPassword { get; set; }
public string ConfirmPassword { get; set; }
public string ConfirmDigitalSignture { get; set; }
}
位置:
public class Location
{
public int ID { get; set; }
public int ParentId { get; set; }
public int TypeId { get; set; }
public int Code { get; set; }
public string Name { get; set; }
}
对于单一模型[for example: User Model]
我知道如果我使用下面的标准html输入,它会将我的数据作为基于其Name attribute
的引用模型发送到控制器:
查看:
@model User
<input name="UserName" Id="UserName" type="text" />
控制器:
public ActionResult Submit(User user)
{
//user.UserName is filled here
}
现在我的问题是如何命名我的标准HTML元素以将数据作为我的视图模型(包含多个模型)发送到控制器?使用html.helper我会引用它,例如:
@Html.TextBoxFor(x => x.User.UserName)
它会在下面吗?
<input type="Text" name="User.UserName" id="User.UserName">
还是其他什么?因为我已经尝试过,但它仍然在表单提交时将值作为null发送。
更新
我已经排除了表单上的其他字段,它们基于html.helpers并正确传递了值,但是有2个字段无效,其中一个字段为Gender
,第二个字段为BirthDate
,因为User Model继承自Person模型,我也会在这里添加它:
人物模型:
public class Persons
{
public bool Gender { get; set; }
public Datetime BirthDate { get; set; }
}
这是我的观点
@model Models.MemberRegisterVM
@{
Layout = "~/Views/Shared/_SiteLayout.cshtml";
}
@using Entities.Texts;
@using (@Html.BeginForm("Register", "MembershipAuth", FormMethod.Post))
{
<div class="form-horizontal">
<div class="col-sm-6">
<div class="col-sm-12">
<div class="control-label col-sm-2">
@Labels.Gender
</div>
<div class="col-sm-5">
<input name="User.Gender" type="radio" id="men_gender" value="0" />
<label for="men_gender">@Labels.Male</label>
</div>
<div class="col-sm-5">
<input name="User.Gender" type="radio" id="female_gender" value="1" />
<label for="female_gender">@Labels.Female</label>
</div>
</div>
</div>
<div class="form-group">
<div class="col-sm-12">
<div class="control-label col-sm-2">
@Labels.BirthDay
</div>
<div class="col-sm-10">
<input type="text" name="User.BirthDate" id="User_BirthDate" />
</div>
</div>
</div>
<div class="form-group">
<div class="col-sm-12">
<div class="g-recaptcha" data-sitekey="6LfLWCkUAAAAAPSp-Fr8bp5egiX8Pw7oKxzZbkmk" style="text-align: center"></div>
</div>
</div>
<div class="form-group">
<input type="submit" class="btn btn-primary" value="Sign Up" />
</div>
</div>
</div>
}
这是我在控制器上的ActionResult
:
[HttpPost]
[AllowAnonymous]
public ActionResult Register(Models.MemberRegisterVM vm, FormCollection form)
{
//vm.User.Gender is not filled here as well as vm.User.BirthDate
}
答案 0 :(得分:1)
您的name
属性是正确的,但是您的Gender
属性无法正确绑定(值始终为false
),因为您生成的单选按钮的值为0
和1
。要绑定到bool
,他们需要True
和False
的值,例如
<input name="User.Gender" type="radio" id="men_gender" value="True" />
虽然您的媒体资源名称/类型对Gender
没有任何意义(要么使用“男性”和“女性”将类型设为enum
,要么将名称更改为bool IsMale
会更合适)
您尚未提供有关BirthDate
属性的发布值的足够详细信息,但如果其未绑定,则很可能是由于日期格式与服务器文化不匹配(例如,如果已发布值7/24/2017,但服务器具有接受dd/MM/yyyy
格式的日期的文化。
尚不清楚为什么要手动生成html。您丢失的双向模型绑定(例如,如果您编辑现有数据或需要返回视图,因为ModelState
无效,控件将不会显示正确的值),并且您没有得到任何客户端验证。至少您应该检查POST方法中ModelState
的值,以查看已添加的验证错误。
作为旁注,自从绑定到模型后,没有理由在方法中包含FormCollection form
参数。
答案 1 :(得分:0)
首先看一下我建议你: -
尽可能使用@Html助手
@Html.TextBoxFor(x => x.User.UserName)
View Models应该是简单或复杂的对象,但不能从任何类派生,因为它只是一个数据传输对象,这将帮助您从MVC默认模型绑定器和模型状态提供程序中获得最大收益,使您的代码更多通过避免编写表单集合或Request.Form看看Here
对于日期时间,您可以使用字符串模型属性并手动转换或覆盖global.asax中的默认模型绑定器行为,例如
ModelBinders.Binders[typeof(DateTime)] =
new DateAndTimeModelBinder() { CustomFormat = "yyyy-mm-dd" };
或根据javascript选择器的任何格式
在这些观点之后我们可以说: - 在MVC中
@Html.TextBoxFor(x => x.User.UserName)
等于
<input type="Text" name="User.UserName" id="User_UserName">
或
<input type="Text" name="User.UserName" id="User.UserName">
id与名称无关紧要,这里的重点是,只有当此属性是简单或复杂VM对象属性之一而不是派生属性时,模型绑定器才会默认绑定它
我希望这有任何帮助。