Validation not working in partial view

2019-06-22 09:12发布

问题:

I have an Index page which has two partial views: login and register.I am using data model validation.

Login.cshtml

@model Project.ViewModel.UserModel

<div style="position:inherit;">
@using (Html.BeginForm("_Login", "account"))
{
    @Html.ValidationSummary(true)
    <div class="label">@Html.Label("Username")</div>
    <div class="field">@Html.TextBoxFor(m => m.Username)</div>
    <div class="error">@Html.ValidationMessageFor(model => model.Username)</div>

    <div class="label">@Html.Label("Password")</div>
    <div class="field">@Html.PasswordFor(m => m.Password)</div>
    <div class="error">@Html.ValidationMessageFor(model => model.Password)</div>

    <input class="field" id="submit" type="submit" value="Login" />
}

Register.cshtml

@model Project.ViewModel.UserModel

<link href="~/Content/Site.css" rel="stylesheet" />
<div style="position: inherit; margin-top: 20px">
@using (Html.BeginForm("_Register","account"))
{
    <div class="label">@Html.Label("Name")</div>
    <div class="field">@Html.TextBoxFor(m => m.FullName)</div>
    <div class="error">@Html.ValidationMessageFor(model => model.FullName)</div>

    <div class="label">@Html.Label("Username")</div>
    <div class="field">@Html.TextBoxFor(m => m.Username)</div>
    <div class="error">@Html.ValidationMessageFor(model => model.Username)</div>

    <div class="label">@Html.Label("Password")</div>
    <div class="field">@Html.PasswordFor(m => m.Password)</div>
    <div class="error">@Html.ValidationMessageFor(model => model.Password)</div>

    <div class="label">@Html.Label("Confirm Password")</div>
    <div class="field">@Html.PasswordFor(m => m.ConfirmPassword)</div>
    <div class="error">@Html.ValidationMessageFor(model => model.Password)</div>

    <div class="label">@Html.Label("Email")</div>
    <div class="field">@Html.TextBoxFor(m => m.Email)</div>
    <div class="error">@Html.ValidationMessageFor(model => model.Email)</div>

    <div class="label">@Html.Label("Country")</div>
    <div class="field">@Html.TextBoxFor(m => m.Country)</div>
    <div class="error">@Html.ValidationMessageFor(model => model.Email)</div>

    <input class="field" id="submit" type="submit" value="Sign Up" />
    @Html.ValidationSummary()   
}

Index.cshtml

 @model Project.ViewModel.UserModel
 @{
    ViewBag.Title = "Index";
    Layout = "~/Views/Shared/_Layout.cshtml";
 }

<div id="regiserandlogin">
<div id="registerandlogin-header">
    <label style="margin-left:50px;">Sign Up For Free!!!</label>
    <label style="margin-left:350px;color:#28a1e2">Already Have An Account?</label>
   </div>
   <div id="registerbox">
        @Html.Partial("_Register", new ProjectHub.ViewModel.UserModel())
   </div>
   <div id="loginbox">
        @Html.Partial("_Login", new ProjectHub.ViewModel.UserModel())
   </div>

    public ViewResult _Register()
    {
        return View("_Register");
    }
    [HttpPost]
    public ActionResult _Register(UserModel usermodel)
    {
        if (!ModelState.IsValid)
        {
            return View("Index");
        }
        try
        {
            FormsAuthentication.SetAuthCookie(usermodel.Username, false);
            return RedirectToAction("activationemail", new {username= Username});
        }
        catch (Exception ae)
        {
            ModelState.AddModelError("", ae.Message);
            return View();
        }
    }
   public ViewResult _Login()
    {
        return View("_Login");
    }
    [HttpPost]
    public ActionResult _Login(string username, string password)
    {
        if (ModelState.IsValid)
        {
            if (MembershipService.ValidateUser(username, password))
            {
                if (!repository.IsVerified(username))
                {
                    ModelState.AddModelError("","Account is not activated.;
                    return View();

                }
                FormsAuthentication.SetAuthCookie(username,false);
                  return RedirectToAction("Index","Home");

            }
            return RedirectToAction("Index", "account"); ;    
        }
        else
        {
            ModelState.AddModelError("","Invalid Username/Password");
            return View();
        }
    }

UserModel.cs

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web;

namespace ProjectHub.ViewModel
{
    public class UserModel
    {
         [Required(ErrorMessage="Username is Required")]
         public string Username { get; set; }
         [Required(ErrorMessage = "Password is Required")]
         public string Password { get; set; }
         [Required(ErrorMessage = "Password is Required")]
         public string ConfirmPassword { get; set; }
         [Required(ErrorMessage = "Name is Required")]
         public string FullName { get; set; }
         [Required(ErrorMessage = "Email is Required")]
         public string Email { get; set; }
         [Required(ErrorMessage = "Country is Required")]
         public string Country { get; set; }
     }
 }

When I press register button like this, I get a validation error

If I use RedirectToAction Method, I don't get the validation error. Please advise me.

回答1:

You should not use the same view model for both partials. You should have 2 different view models.

For example:

public class LoginViewModel
{
    [Required(ErrorMessage="Username is Required")]
    public string Username { get; set; }

    [Required(ErrorMessage = "Password is Required")]
    public string Password { get; set; }
}

and for the register partial:

public class RegisterViewModel
{
     [Required(ErrorMessage="Username is Required")]
     public string Username { get; set; }

     [Required(ErrorMessage = "Password is Required")]
     public string Password { get; set; }

     [Required(ErrorMessage = "Password is Required")]
     public string ConfirmPassword { get; set; }

     [Required(ErrorMessage = "Name is Required")]
     public string FullName { get; set; }

     [Required(ErrorMessage = "Email is Required")]
     public string Email { get; set; }

     [Required(ErrorMessage = "Country is Required")]
     public string Country { get; set; }
}

and then your main view model should aggregate those 2 view models:

public class MyViewModel
{
    public LoginViewModel Login { get; set; }
    public LoginViewModel Register { get; set; }
}

and then:

<div id="registerbox">
    @Html.Partial("_Register", Model.Login)
</div>
<div id="loginbox">
    @Html.Partial("_Login", Model.Register)
</div>


回答2:

Add the following reference to the JQuery scripts in your View.
I went through the same situation and it solved my problem.

"~/Scripts/jquery.unobtrusive*"
"~/Scripts/jquery.validate*"