2

I've been trying to learn asp.net MVC coming from a webforms background and I believe I didn't get the idea of actions, controllers and their relation to partials very well...

I have a _Layout.cshtml file that includes a _LoginPartial.cshtml (it's not the default code from Visual Studio, just the same name) and a Home/Index.cshtml file which includes the same partial (_LoginPartial) as well, here's the code for the partial:

@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>
    }
}

so the _Layout.cshtml file includes the _LoginPartial.cshtml with the following code (no form tag inside _Layout.cshtml):

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

and the Home/Index.cshtml includes the same partial with the following code (no form tag besides the one inside _LoginPartial either):

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

so instead of using the default "AccountController" I decided to create a new one (PostController) to try, the partial above posts it's data successfully to ProfileController, but when the data is incorrect the ValidationMessage is always empty, here's the code to my controller:

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");
    }
} 

as you can see, the partial is accessed via Home/Index.cshtml but its controller is located at Profile/Login, so when it redirects back to the Home/Index page no validation message is shown...

my question is: am I doing the right thing? how can I show the ValidationMessage from my model? if I'm not doing the right thing, how these actions and controllers are supposed to be structured to be true to the MVC model?

and just for sake of completeness, here's my LoginModel class:

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; }
}
4

1 回答 1

1

您正在做正确的事情,但是就像那样,您是否有Required注释的验证消息?还是只是缺少您添加到模型状态的那个?如果所有这些都缺少

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

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

无论如何,添加到模型状态的错误没有让 MVC 显示的地方,你需要一些类似的@Html.ValidationSummary(true)东西为你

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

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

于 2013-08-02T14:58:45.673 回答