c#MVC嵌套模型不从视图返回

时间:2015-07-05 17:10:33

标签: c# asp.net-mvc

我有一个MasterModel类,它基本上为共享布局中的部分视图处理大​​量数据。但是,当我尝试以一种形式(例如“登录”)返回对象的一部分(或整个MasterModel)时,没有数据传递给控制器​​。

以下是MasterModel的一部分:

public class MasterModel
{
    public Login Login;
    public Account Account;
    public User User;

    public MasterModel()
    {
        Login = new Login();
        Account = new Account();
        User = new User();
    }
}

以下是登录的一部分:

public class Login
{
    public string Email {get;set;}
    public string PasswordHash {get; private set;
    public string FName {get;set;}
}

以下是主布局模板的一部分,该模板调用登录的部分视图:

@model Models.MasterModel
...
@{
     Html.RenderPartial("../Partials/_Login", Model.Login);
}
...

这是_Login partial:

@model Models.Login
<div class="login-bar">

    @if (Model != null && !string.IsNullOrWhiteSpace(Model.FName) )
    {
        var welcomeString = "Welcome back, " + Model.FName;
        <p>@Html.ActionLink(welcomeString, "Overview", "Account")</p>
    }
    else
    {
        using (Html.BeginForm("Login", "Account", FormMethod.Post))
        {
            @Html.AntiForgeryToken()

            <p>
                @Html.Label("Email Address:")
                @Html.EditorFor(login => login.Email, new { @class = "email" })

                @Html.Label("Password:")
                @Html.PasswordFor(login => login.PasswordHash)
                <input type="submit" value="Login" class="button" />

                @if (ViewBag.Message != null)
                {
                    <shim class="red">@ViewBag.Message.ToString()</shim>
                }
            </p>
        }
    }

</div>

这里也是HttpPost for Login的AccountController:

[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Login(Login login, string returnUrl)
{
    var master = new MasterModel();
    // ModelState is valid. login.Email = "" and login.PasswordHash is still default
    if (ModelState.IsValid && (!string.IsNullOrEmpty(login.Email) && !string.IsNullOrEmpty(login.PasswordHash)))
    {
        var user = await UserManager.FindAsync(login.Email, login.PasswordHash);
        if (user != null)
        {
            await SignInAsync(user, true);
            master.User = user;
            return RedirectToAction("Overview", "Account", master);
        }
    }
    return View(master);
}

我也尝试将整个MasterModel传递给局部视图(也改变@model使用Models.MasterModel),同时访问Login属性作为masterModel.Login.Email等,但无济于事。

它必须是非常简单的东西,我对属性名称的绑定缺失了,但我现在开始盲目编码了!

有什么想法吗?

[更新] - 添加了AccountController

2 个答案:

答案 0 :(得分:1)

经过7个小时的狩猎,我现在可以踢自己了。

我上面发布的登录模型缺少一件我选择忽略速度的东西。这是我在上面的原始问题中看起来应该是什么样的:

public class Login
{
    public string Email {get; private set;}
    public string PasswordHash {get; private set;} 
    public string FName {get; private set;}
} 

将这些更改为公共属性(虽然PasswordHash稍有不同)已经解决了丢失对象的神秘面纱:

public class Login
{
    public string Email {get;set;}
    public string PasswordHash {get; set;} // Not actual implementation. Applies it's own crypto first
    public string FName {get;set;}
}

希望这可以帮助别人(以及我在几周内再次!)将头撞在墙上!

答案 1 :(得分:0)

一切似乎都没问题。您可以尝试将登录操作中的参数重命名为登录以外的内容

public async Task<ActionResult> Login(Login model, string returnUrl)

也许你的部分

也一样

@Html.EditorFor(model => model.Email, new { @class = "email" })