【问题标题】:c# MVC Nested models not returning from viewsc#MVC嵌套模型不从视图返回
【发布时间】:2015-07-06 02:49:43
【问题描述】:

我有一个 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 部分:

@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 的 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),同时以 masterModel.Login.Email 等方式访问 Login 属性,但无济于事。

我在属性名称上的绑定中缺少一些非常简单的东西,但我现在开始盲目编码!

有什么想法吗?

[更新] - 添加了 AccountController

【问题讨论】:

  • 您是否尝试过使用像 Fiddler 这样的程序来查看哪些信息被传递到了哪里? telerik.com/fiddler
  • 检查了 Chrome 中的标题,一切似乎都很好。 ...&Email= ...&PasswordHash= ... 就在那里。甚至查看了渲染的 HTML,ID 和名称分别是“Email”和“PasswordHash”。

标签: c# asp.net-mvc


【解决方案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;}
}

希望这可以帮助其他人(以及几周后我自己!)免于将头撞到墙上!

【讨论】:

    【解决方案2】:

    一切似乎都很好。您可以尝试将登录操作中的参数重命名为登录以外的其他名称

    public async Task&lt;ActionResult&gt; Login(Login model, string returnUrl)

    也许在你的部分做同样的事情

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

    【讨论】:

    • 修改了控制器和视图以使用“模型”,仍然有同样的问题。几周前我在命名约定方面遇到了类似的问题,但我一生都记不起我做了什么来解决它!去搜索之前签入的代码,看看我哪里出错了。
    • 有趣。我更改了 AccountController Login(Login model, string returnUrl) 以仅获取响应中的两个字段 - Login(string email, string passwordHash) 并且这两个项目被正确地反馈给控制器。知道为什么 Login 对象没有被发回吗?
    猜你喜欢
    • 2012-02-12
    • 1970-01-01
    • 2017-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-22
    • 2015-11-27
    • 1970-01-01
    相关资源
    最近更新 更多