IValidatableObject 验证方法不起作用

发布于 2024-12-23 09:15:42 字数 5860 浏览 0 评论 0原文

我在 MVC3 中使用了此类...

每个属性的验证属性都正常工作,但是当调用 Validate 方法并返回任何结果时,它不会回发到表单。 有人可以帮忙吗?

public class Register : IValidatableObject
{
    [DataType(DataType.Text)]
    [Display(Name = "District Name")]
    [Required(AllowEmptyStrings = false, ErrorMessage = "You must enter a District Name")]
    [StringLength(40, MinimumLength = 1, ErrorMessage = "District Name must be between 1 and 40 characters")]
    public string DistrictName { get; set; }

    [DataType(DataType.Text)]
    [Display(Name = "Url Quick Find")]
    [Required(ErrorMessage = "You must provide a Quick Find Name")]
    [StringLength(15, MinimumLength = 3, ErrorMessage = "Url Quick Find must be between 3 and 15 characters")]
    public string QuickFind { get; set; }

    [DataType(DataType.Text)]
    [Display(Name = "User name")]
    [Required(AllowEmptyStrings = false, ErrorMessage = "User name is requred")]
    [StringLength(10, MinimumLength = 1, ErrorMessage = "Url Quick Find must be between 1 and 10 characters")]
    public string Username { get; set; }

    [DataType(DataType.Password)]
    [Display(Name = "Password")]
    [Required(AllowEmptyStrings = false, ErrorMessage = "Password is requred")]
    public string Password { get; set; }

    [DataType(DataType.Password)]
    [Display(Name = "Re-Enter Password")]
    [Required(AllowEmptyStrings = false, ErrorMessage = "You must re-enter your password to confirm you have entered it correctly")]
    public string PasswordConfirm { get; set; }

    [DataType(DataType.Text)]
    [Display(Name = "Display Name")]
    [Required(AllowEmptyStrings = false, ErrorMessage = "Display Name is requred")]
    [StringLength(20, MinimumLength = 1, ErrorMessage = "Display Name must be between 1 and 20 characters")]
    public string DisplayName { get; set; }

    [DataType(DataType.EmailAddress)]
    [Display(Name = "Email Address")]
    [Required(AllowEmptyStrings = false, ErrorMessage = "Email Address is requred")]
    [StringLength(50, MinimumLength = 4, ErrorMessage = "Email Address must be between 4 and 50 characters")]
    public string EmailAddress { get; set; }

    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
    {
        Regex lettersOnly = new Regex("^[a-zA-Z]*$");

        if (!lettersOnly.IsMatch(QuickFind))
            yield return new ValidationResult("Only letters A - Z are allowed in the Quick Find", new string[] { "QuickFind" });

        if (!lettersOnly.IsMatch(QuickFind))
            yield return new ValidationResult("Only letters A - Z are allowed for your User name", new string[] { "Username" });

        if (Password != PasswordConfirm)
            yield return new ValidationResult("Passwords do not match", new string[] { "Password", "PasswordConfirm" });

    }
}

控制器代码:

[HttpPost]
    public ActionResult Index(Register registration)
    {
        try
        {
            User newUser = RegistrationManager.Register(registration);
            RedirectToAction("Index", "District", newUser.ID);
        }
        catch (Exception ex)
        {
            ModelState.AddModelError("There has been an Error during Registration", ex.Message);
            RedirectToAction("Details", "Error", ex);
        }

        return View();
    }

查看代码:

@model PubGames.Data.Register
@{
    ViewBag.Title = "Register";
}
<h2>
    Register</h2>
<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")"     type="text/javascript"></script>
@using (Html.BeginForm())
{
    @Html.ValidationSummary(true)

    <div class="editor-label">
        @Html.LabelFor(model => model.DistrictName)
    </div>
    <div class="editor-field">
        @Html.EditorFor(model => model.DistrictName)
        @Html.ValidationMessageFor(model => model.DistrictName)
    </div>

    <div class="editor-label">
        @Html.LabelFor(model => model.QuickFind)
    </div>
    <div class="editor-field">
        @Html.EditorFor(model => model.QuickFind)
        @Html.ValidationMessageFor(model => model.QuickFind)
    </div>

    <div class="editor-label">
        @Html.LabelFor(model => model.Username)
    </div>
    <div class="editor-field">
        @Html.EditorFor(model => model.Username)
        @Html.ValidationMessageFor(model => model.Username)
    </div>

    <div class="editor-label">
        @Html.LabelFor(model => model.Password)
    </div>
    <div class="editor-field">
        @Html.EditorFor(model => model.Password)
        @Html.ValidationMessageFor(model => model.Password)
    </div>

    <div class="editor-label">
        @Html.LabelFor(model => model.PasswordConfirm)
    </div>
    <div class="editor-field">
        @Html.EditorFor(model => model.PasswordConfirm)
        @Html.ValidationMessageFor(model => model.PasswordConfirm)
    </div>

    <div class="editor-label">
        @Html.LabelFor(model => model.DisplayName)
    </div>
    <div class="editor-field">
        @Html.EditorFor(model => model.DisplayName)
        @Html.ValidationMessageFor(model => model.DisplayName)
    </div>

    <div class="editor-label">
        @Html.LabelFor(model => model.EmailAddress)
    </div>
    <div class="editor-field">
        @Html.EditorFor(model => model.EmailAddress)
        @Html.ValidationMessageFor(model => model.EmailAddress)
    </div>

    <p>
        <input type="submit" value="Register" />
    </p>
} 

I have this class used in MVC3...

The Validation Attributes for each property are working as it should but when the Validate method is called and any results are returned it is not posting back to the form.
Can anyone help??

public class Register : IValidatableObject
{
    [DataType(DataType.Text)]
    [Display(Name = "District Name")]
    [Required(AllowEmptyStrings = false, ErrorMessage = "You must enter a District Name")]
    [StringLength(40, MinimumLength = 1, ErrorMessage = "District Name must be between 1 and 40 characters")]
    public string DistrictName { get; set; }

    [DataType(DataType.Text)]
    [Display(Name = "Url Quick Find")]
    [Required(ErrorMessage = "You must provide a Quick Find Name")]
    [StringLength(15, MinimumLength = 3, ErrorMessage = "Url Quick Find must be between 3 and 15 characters")]
    public string QuickFind { get; set; }

    [DataType(DataType.Text)]
    [Display(Name = "User name")]
    [Required(AllowEmptyStrings = false, ErrorMessage = "User name is requred")]
    [StringLength(10, MinimumLength = 1, ErrorMessage = "Url Quick Find must be between 1 and 10 characters")]
    public string Username { get; set; }

    [DataType(DataType.Password)]
    [Display(Name = "Password")]
    [Required(AllowEmptyStrings = false, ErrorMessage = "Password is requred")]
    public string Password { get; set; }

    [DataType(DataType.Password)]
    [Display(Name = "Re-Enter Password")]
    [Required(AllowEmptyStrings = false, ErrorMessage = "You must re-enter your password to confirm you have entered it correctly")]
    public string PasswordConfirm { get; set; }

    [DataType(DataType.Text)]
    [Display(Name = "Display Name")]
    [Required(AllowEmptyStrings = false, ErrorMessage = "Display Name is requred")]
    [StringLength(20, MinimumLength = 1, ErrorMessage = "Display Name must be between 1 and 20 characters")]
    public string DisplayName { get; set; }

    [DataType(DataType.EmailAddress)]
    [Display(Name = "Email Address")]
    [Required(AllowEmptyStrings = false, ErrorMessage = "Email Address is requred")]
    [StringLength(50, MinimumLength = 4, ErrorMessage = "Email Address must be between 4 and 50 characters")]
    public string EmailAddress { get; set; }

    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
    {
        Regex lettersOnly = new Regex("^[a-zA-Z]*$");

        if (!lettersOnly.IsMatch(QuickFind))
            yield return new ValidationResult("Only letters A - Z are allowed in the Quick Find", new string[] { "QuickFind" });

        if (!lettersOnly.IsMatch(QuickFind))
            yield return new ValidationResult("Only letters A - Z are allowed for your User name", new string[] { "Username" });

        if (Password != PasswordConfirm)
            yield return new ValidationResult("Passwords do not match", new string[] { "Password", "PasswordConfirm" });

    }
}

Controller Code:

[HttpPost]
    public ActionResult Index(Register registration)
    {
        try
        {
            User newUser = RegistrationManager.Register(registration);
            RedirectToAction("Index", "District", newUser.ID);
        }
        catch (Exception ex)
        {
            ModelState.AddModelError("There has been an Error during Registration", ex.Message);
            RedirectToAction("Details", "Error", ex);
        }

        return View();
    }

View Code:

@model PubGames.Data.Register
@{
    ViewBag.Title = "Register";
}
<h2>
    Register</h2>
<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")"     type="text/javascript"></script>
@using (Html.BeginForm())
{
    @Html.ValidationSummary(true)

    <div class="editor-label">
        @Html.LabelFor(model => model.DistrictName)
    </div>
    <div class="editor-field">
        @Html.EditorFor(model => model.DistrictName)
        @Html.ValidationMessageFor(model => model.DistrictName)
    </div>

    <div class="editor-label">
        @Html.LabelFor(model => model.QuickFind)
    </div>
    <div class="editor-field">
        @Html.EditorFor(model => model.QuickFind)
        @Html.ValidationMessageFor(model => model.QuickFind)
    </div>

    <div class="editor-label">
        @Html.LabelFor(model => model.Username)
    </div>
    <div class="editor-field">
        @Html.EditorFor(model => model.Username)
        @Html.ValidationMessageFor(model => model.Username)
    </div>

    <div class="editor-label">
        @Html.LabelFor(model => model.Password)
    </div>
    <div class="editor-field">
        @Html.EditorFor(model => model.Password)
        @Html.ValidationMessageFor(model => model.Password)
    </div>

    <div class="editor-label">
        @Html.LabelFor(model => model.PasswordConfirm)
    </div>
    <div class="editor-field">
        @Html.EditorFor(model => model.PasswordConfirm)
        @Html.ValidationMessageFor(model => model.PasswordConfirm)
    </div>

    <div class="editor-label">
        @Html.LabelFor(model => model.DisplayName)
    </div>
    <div class="editor-field">
        @Html.EditorFor(model => model.DisplayName)
        @Html.ValidationMessageFor(model => model.DisplayName)
    </div>

    <div class="editor-label">
        @Html.LabelFor(model => model.EmailAddress)
    </div>
    <div class="editor-field">
        @Html.EditorFor(model => model.EmailAddress)
        @Html.ValidationMessageFor(model => model.EmailAddress)
    </div>

    <p>
        <input type="submit" value="Register" />
    </p>
} 

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

森林散布 2024-12-30 09:15:42

这么多问题......

一个典型的 Action 方法是这样的:

public ActionResult DoSomething(MyModel model)
{
    if (ModelState.IsValid)
    {
        return RedirectToAction("somethign");
    }
    return View(model);
}

这会做几件事,但主要是如果模型状态无效,它会将模型状态返回到视图。您没有这样做,事实上您甚至没有将模型返回到视图。您没有检查状态是否有效,因此即使服务器端验证失败,它也会尝试调用注册方法。您也没有返回您的 ActionResults,即 RedirectToAction,您只是调用它。

So many problems...

A typical Action method goes like this:

public ActionResult DoSomething(MyModel model)
{
    if (ModelState.IsValid)
    {
        return RedirectToAction("somethign");
    }
    return View(model);
}

This does several things, but primarily it returns the model state back to the view if it is not valid. You are not doing that, and in fact you're not even return the model back to the view. You're not checking if the state is valid, so it will try and call the register method even if validation fails serverside. You're also not returning your ActionResults, ie RedirectToAction, you're just calling it..

梦萦几度 2024-12-30 09:15:42

您没有正确重定向。您必须返回 RedirectToAction:

[HttpPost]
public ActionResult Index(Register registration)
{
    try
    {
        User newUser = RegistrationManager.Register(registration);
        return RedirectToAction("Index", "District", newUser.ID);
    }
    catch (Exception ex)
    {
        ModelState.AddModelError("There has been an Error during Registration", ex.Message);
        return RedirectToAction("Details", "Error", ex);
    }

    return View(registration);
}

此外,当您在异常情况下重定向时,您将丢失添加到模型状态的任何错误。

You are not redirecting correctly. You must return RedirectToAction:

[HttpPost]
public ActionResult Index(Register registration)
{
    try
    {
        User newUser = RegistrationManager.Register(registration);
        return RedirectToAction("Index", "District", newUser.ID);
    }
    catch (Exception ex)
    {
        ModelState.AddModelError("There has been an Error during Registration", ex.Message);
        return RedirectToAction("Details", "Error", ex);
    }

    return View(registration);
}

Also when you redirect in the case of exception you will lose any errors that you have added to the modelstate.

怼怹恏 2024-12-30 09:15:42

你是什​​么意思“不发回表单” - 你的意思是错误没有出现?
确保

  1. 您在页面上有验证摘要,
  2. 您发布帖子后是否没有重定向。
  3. 请注意,这不是为了客户端验证(只是说,您可能已经知道了)

How do you mean "not posting back to the form" - you mean the errors on't show up?
Ensure

  1. You have a validation summary on the page
  2. Are you NOT redirecting after your post.
  3. be aware this isn't for client validation (just saying, you may already be aware)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文