【问题标题】:how to make the model validate a partial view that comes from a different controller?如何使模型验证来自不同控制器的局部视图?
【发布时间】:2013-08-03 21:15:57
【问题描述】:

我一直在尝试从 webforms 背景学习 asp.net MVC,但我相信我没有很好地理解动作、控制器及其与部分的关系......

我有一个 _Layout.cshtml 文件,其中包含一个 _LoginPartial.cshtml (它不是 Visual Studio 的默认代码,只是同名) em> 和一个 Home/Index.cshtml 文件,其中也包含相同的部分 (_LoginPartial),这是部分的代码:

@model LoginModel
@if (Request.IsAuthenticated) {
    @*<welcome text here>*@
} else {
    if ( Model.Layout == LoginLayout.Compact ) {
        @*<simple layout here>*@
    } else {
        <form method="post" action="~/Profile/Login">
            @Html.AntiForgeryToken()

            @Html.LabelFor(m => m.Email, "Email Field")
            @Html.TextBoxFor(m => m.Email)
            @Html.ValidationMessageFor(m => m.Email)

            @Html.LabelFor(m => m.Password, "Password Field")
            @Html.PasswordFor(m => m.Password)
            @Html.ValidationMessageFor(m => m.Password)

            @Html.ValidationSummary()
        </form>
    }
}

所以 _Layout.cshtml 文件包含带有以下代码的 _LoginPartial.cshtml(_Layout.cshtml 内没有表单标签):

@Html.Partial("_LoginPartial", new LoginModel())

并且 Home/Index.cshtml 包含相同的部分,并带有以下代码(除了 _LoginPartial 中的一个之外没有表单标记):

@Html.Partial("_LoginPartial", new LoginModel() {
    Layout = LoginLayout.Full
})

所以我决定创建一个新的(PostController)来尝试,而不是使用默认的“AccountController”,上面的部分将其数据成功发布到ProfileController,但是当数据不正确时ValidationMessage 始终为空,这是我的控制器的代码:

public class ProfileController : BaseController
{
    [HttpPost]
    [AllowAnonymous]
    [ValidateAntiForgeryToken]
    public ActionResult Login(LoginModel form)
    {
        if (ModelState.IsValid)
        {
            //code to validate the user here
            if (userIsValid)
            {
                FormsAuthentication.SetAuthCookie(form.Email, false);
                return RedirectToAction("Index");
            }
        }

        ModelState.AddModelError("", "The user name or password provided is incorrect.");
        return RedirectToAction("Index", "Home");
    }
} 

如您所见,部分是通过 Home/Index.cshtml 访问的,但其控制器位于 Profile/Login 中,因此当它重定向回 Home/Index 页面时,不会显示验证消息...

我的问题是:我做对了吗?如何从我的模型中显示 ValidationMessage?如果我没有做正确的事情,这些动作和控制器应该如何构建以符合 MVC 模型?

为了完整起见,这是我的 LoginModel 类:

public enum LoginLayout {
    Compact,
    Full
}
public class LoginModel
{
    public LoginLayout Layout { get; set; }

    [Required(ErrorMessage = "Please enter your e-mail")]
    [DataType(DataType.EmailAddress)]
    public string Email { get; set; }

    [Required(ErrorMessage = "Please enter your password")]
    [DataType(DataType.Password)]
    public string Password { get; set; }
}

【问题讨论】:

标签: c# asp.net-mvc validation asp.net-mvc-4 razor


【解决方案1】:

你做的很对,但是就像那样,你有Required注解的验证信息吗?还是只是缺少您添加到模型状态的那个? 如果所有这些都丢失了

@Html.Partial("_LoginPartial", new LoginModel())

可能是问题所在,您是否尝试过@Html.EditorFor(编辑:忘记提及您应该将局部视图 _LoginPartial 移动到根编辑器模板文件夹)?您还应该将其用于密码和电子邮件顺便说一句。

无论如何,添加到模型状态的错误没有让 MVC 显示的地方,您将需要类似于 @Html.ValidationSummary(true) 的内容我想记得阅读有关仅显示特定验证错误的内容,让我看看我能不能帮你挖出来

编辑:刚刚发现,也使用@using(@Html.BeginForm(,而不是手动放置这样的表单,它更容易且对 Razor 更友好(稍后您将能够很容易地对其进行 ajaxify,我建议将其用于日志记录这样的形式)

编辑2:哈哈这就是我要说的,link,这里的答案将允许您显示特定的模型状态错误(如果存在),但是您需要在添加时给它一个键它到模型状态

【讨论】:

  • 嘿,西蒙,非常感谢,我尝试了你所说的一切,但唯一对我有用的是我在 Erik Philips 发布的重复链接中发现的,再次感谢!
  • 嗯没问题,只是一个简单的问题,这就像您保留在页面顶部的登录表单吗?类似的东西?
  • 确切地说,在我的布局中,我使用相同的部分在页面顶部呈现“注册|登录”,然后在登录页面上呈现完整的表单...是不是很糟糕练习这样做吗?再次感谢!
  • 当然不是,特别是如果您的几个页面具有公共/匿名访问权限,只是想确保我理解您最初的问题是正确的。不过,我建议在某处保留一个重定向网址,并在用户成功登录后将其重定向到那里,这样他们就不必重新导航到他们想要访问的页面。
猜你喜欢
  • 2017-04-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-27
  • 2019-03-29
  • 1970-01-01
相关资源
最近更新 更多