C# MVC 5-当一个对象是页面视图模型的属性时,如何将该对象映射到一个动作?

C# MVC 5-当一个对象是页面视图模型的属性时,如何将该对象映射到一个动作?,c#,asp.net-mvc,razor,C#,Asp.net Mvc,Razor,我有一个这样定义的登录视图模型 public class LoginViewModel { [Required] public String Username { get; set; } [Required] [DataType(DataType.Password)] public String Password { get; set; } /// <summary> /// The default constructor

我有一个这样定义的登录视图模型

public class LoginViewModel
{
    [Required]
    public String Username { get; set; }

    [Required]
    [DataType(DataType.Password)]
    public String Password { get; set; }


    /// <summary>
    /// The default constructor.
    /// </summary>
    public LoginViewModel()
    {

    }
}
我的母版页采用的基本视图模型定义为:

public abstract class CommonViewModel
{
    #region Properties
    public LoginViewModel LoginModel { get; set; }                
    #endregion

    #region Functions

    /// <summary>
    /// The default constructor.
    /// </summary>
    public CommonViewModel()
    {

    }

    #endregion
}
在主布局中,我有一个登录表单。这张表格是这样安排的

<form id="login-form" method="post" action="@Url.Action("Login", "Account")">
    <div class="form-element">                            
        @Html.LabelFor(m => m.LoginModel.Username, Resources.MasterPageStrings.LoginUsername, new { @class = "login-form-label" })                            
        @Html.TextBoxFor(m => m.LoginModel.Username, new
        {
            @class = "login-form-input login-form-input-common required",
            @autofocus = String.Empty,
            @placeholder = Resources.MasterPageStrings.LoginUsername
        })
    </div>
    <div class="form-element">
        @Html.LabelFor(m => m.LoginModel.Password, Resources.MasterPageStrings.LoginPassword, new { @class = "login-form-label" })
        @Html.TextBoxFor(m => m.LoginModel.Password, new
        {
            @class = "login-form-input login-form-input-common required",
            @placeholder = Resources.MasterPageStrings.LoginPassword,
            @type = "password"
        })
    </div>
    <div class="form-element">
        @Html.LabelFor(m => m.LoginModel.RememberMe, Resources.MasterPageStrings.LoginRememberMe, new { @class = "login-form-label" })
        @Html.CheckBoxFor(m => m.LoginModel.RememberMe, new
        {
            @class = "login-form-input login-form-input-common",
            @placeholder = Resources.MasterPageStrings.LoginRememberMe
        })
    </div>
    <div class="form-element">
        <input type="submit" class="login-form-submit login-form-input-common" value="@Resources.MasterPageStrings.LoginLoginLabel">
    </div>
</form>
当我提交给帐户控制器时,我没有映射登录视图模型

/// <summary>
/// Logs the user into the application.
/// </summary>
/// <param name="model">The login view model uses to login.</param>        
/// <returns>The view you were trying to get to.</returns>
[HttpPost]
[AllowAnonymous]
[Route("Login")]
public async Task<ActionResult> Login(Models.ViewModels.Common.LoginViewModel model)
{

}
视图模型始终是用户名和密码的默认空值null。如何在account controller登录操作中映射登录模型


我无法映射到公共视图模型,因为我遇到无法实例化抽象类的错误。

尝试更改您的登录操作,使其采用公共视图模型而不是LoginView模型

或者更好的做法是,将视图的代码分离为部分视图,将该视图的模型设置为LoginViewModel,并按如下方式渲染部分视图:

@Html.RenderPartial("_LoginView", Model.LoginModel )

假设基础视图上的模型类型为CommonViewModel

局部视图是针对这种情况创建的。 创建部分视图并粘贴登录HTML。将部分视图的模型保留为LoginViewModel,并在母版页中呈现。
就这样

接收null的原因是,如果使用属性,则发送的数据基于视图的模型,即CommonViewModel

@Html.TextBoxFor(m => m.LoginModel.Password, new
                            {
                                @class = "login-form-input login-form-input-common required",
                                @placeholder = Resources.MasterPageStrings.LoginPassword,
                                @type = "password"
                            })
如果您看到呈现的html,名称将是LoginModel.Password,但在操作中,您试图获取没有属性LoginModel.Password的LoginViewModel

所以你的行动应该是

[HttpPost]
[AllowAnonymous]
[Route("Login")]
public async Task<ActionResult> Login(CommonViewModel model)
{
 var loginmodel= model.LoginModel; //here you can access the properties like loginmodel.Password
}
你的行动将是

[HttpPost]
[AllowAnonymous]
[Route("Login")]
public async Task<ActionResult> Login(Models.ViewModels.Common.LoginViewModel model)
{

}

有两种选择。1.您可以从公共vm中删除摘要。2.不要使用普通的虚拟机。3.使用jquery创建模型并将其传递给登录名。问题的概念不是关于公共视图模型,而是如何将控制器映射到作为页面视图模型属性的模型。我经常遇到这种场景,它不涉及公共视图模型。例如,如果有一个视图模型,其中有5个单独的对象,并且有5个动作调用,每个动作调用取5个对象中的一个,该怎么办。简单的回答是:你不能。MVC将绑定到您的根模型,无论控制器操作期望的是什么。@SolidSnake4444它应该是CommonViewModel而不是LoginViewModel当我尝试此操作时,我收到一个错误,说明我无法执行此操作,因为CommonViewModel是抽象的。当我尝试此操作时,我收到一个错误,无法实例化抽象类。我必须再做一次,以找出它发生的确切位置,以提供更多信息。@SolidSnake4444我已用另一种解决方案更新了我的答案
[HttpPost]
[AllowAnonymous]
[Route("Login")]
public async Task<ActionResult> Login(Models.ViewModels.Common.LoginViewModel model)
{

}