如何使用标准HTML将值从视图发送到控制器

时间:2017-07-23 11:42:19

标签: c# asp.net-mvc razor

我有这个视图模型:

public class MemberRegisterVM
{
    public Users User { get; set; }
    public Location Location { get; set; }
}

其中包含UserLocation模型

用户:

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
}

2 个答案:

答案 0 :(得分:1)

您的name属性是正确的,但是您的Gender属性无法正确绑定(值始终为false),因为您生成的单选按钮的值为01。要绑定到bool,他们需要TrueFalse的值,例如

<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对象属性之一而不是派生属性时,模型绑定器才会默认绑定它

我希望这有任何帮助。