ASP.NET MVC 2“价值”当提交不正确的日期时,在 DataAnnotation 属性中的 IsValid 覆盖中传递的值为 null

发布于 2024-08-30 07:32:33 字数 2089 浏览 4 评论 0原文

这是我关于堆栈溢出的第一个问题。 我需要帮助解决我目前正在处理的 ASP.NET MVC2 项目中遇到的问题。 我应该指出,我对 MVC 设计比较陌生,所以请忍受我的无知。 这里是: 我有一个常规表格,上面显示了一个人的各种详细信息。其中之一是“出生日期”。我的观点是这样的,

<div class="form-items">
            <%: Html.Label("DateOfBirth", "Date of Birth:") %>
            <%: Html.EditorFor(m => m.DateOfBirth) %>
            <%: Html.ValidationMessageFor(m => m.DateOfBirth) %>
</div>

我正在使用我找到的编辑器模板,仅正确显示日期:

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<System.DateTime?>"%>
<%= Html.TextBox("", (Model.HasValue ? Model.Value.ToShortDateString() : string.Empty))%>

我使用 LinqToSql 设计器从 sql 数据库创建我的模型。为了进行一些验证,我创建了一个部分类 Person 来扩展设计者创建的部分类(在同一命名空间下):

[MetadataType(typeof(IPerson))]
public partial class Person : IPerson
{        //To create buddy class    }

public interface IPerson
{
    [Required(ErrorMessage="Please enter a name")]
    string Name { get; set; }
    [Required(ErrorMessage="Please enter a surname")]
    string Surname { get; set; }
    [Birthday]
    DateTime? DateOfBirth { get; set; }
    [Email(ErrorMessage="Please enter a valid email")]
    string Email { get; set; }
}

我想确保输入正确的日期。所以我创建了一个自定义 DataAnnotation 属性来验证日期:

public class BirthdayAttribute : ValidationAttribute
{
    private const string _errorMessage = "Please enter a valid date";

    public BirthdayAttribute() : base(_errorMessage) { }

    public override bool  IsValid(object value)
    {
        if (value == null)
        {
            return true;
        }
        DateTime temp;
        bool result = DateTime.TryParse(value.ToString(), out temp);
        return result;
    }
}

嗯,我的问题是这样的。一旦我在 DateOfBirth 字段中输入不正确的日期,即使使用 [Birthday(ErrorMessage=".....")] 等属性,也不会显示任何自定义消息。显示的消息是从数据库返回的消息,即“值‘32/4/1967’对于出生日期无效。”。我尝试在代码周围输入一些断点,发现当日期不正确时,属性中的“值”始终为空,但如果日期格式正确,则总是获得一个值。设计者生成的代码中也会传递相同的值( value == null)。

这件事让我发疯。请问有人能帮我解决这个问题吗? 另外,如果有人可以告诉我从视图到数据库的入口点到底在哪里。与模型绑定器有关吗?因为我想检查按下“提交”按钮后到底传递了什么值。 谢谢。

This is my first question here on stack overflow.
i need help on a problem i encountered during an ASP.NET MVC2 project i am currently working on.
I should note that I'm relatively new to MVC design, so pls bear my ignorance.
Here goes :
I have a regular form on which various details about a person are shown. One of them is "Date of Birth". My view is like this

<div class="form-items">
            <%: Html.Label("DateOfBirth", "Date of Birth:") %>
            <%: Html.EditorFor(m => m.DateOfBirth) %>
            <%: Html.ValidationMessageFor(m => m.DateOfBirth) %>
</div>

I'm using an editor template i found, to show only the date correctly :

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<System.DateTime?>"%>
<%= Html.TextBox("", (Model.HasValue ? Model.Value.ToShortDateString() : string.Empty))%>

I used LinqToSql designer to create my model from an sql database. In order to do some validation i made a partial class Person to extend the one created by the designer (under the same namespace) :

[MetadataType(typeof(IPerson))]
public partial class Person : IPerson
{        //To create buddy class    }

public interface IPerson
{
    [Required(ErrorMessage="Please enter a name")]
    string Name { get; set; }
    [Required(ErrorMessage="Please enter a surname")]
    string Surname { get; set; }
    [Birthday]
    DateTime? DateOfBirth { get; set; }
    [Email(ErrorMessage="Please enter a valid email")]
    string Email { get; set; }
}

I want to make sure that a correct date is entered. So i created a custom DataAnnotation attribute in order to validate the date :

public class BirthdayAttribute : ValidationAttribute
{
    private const string _errorMessage = "Please enter a valid date";

    public BirthdayAttribute() : base(_errorMessage) { }

    public override bool  IsValid(object value)
    {
        if (value == null)
        {
            return true;
        }
        DateTime temp;
        bool result = DateTime.TryParse(value.ToString(), out temp);
        return result;
    }
}

Well, my problem is this. Once i enter an incorrect date in the DateOfBirth field then no custom message is displayed even if use the attribute like [Birthday(ErrorMessage=".....")]. The message displayed is the one returned from the db ie "The value '32/4/1967' is not valid for DateOfBirth.". I tried to enter some break points around the code, and found out that the "value" in attribute is always null when the date is incorrect, but always gets a value if the date is in correct format. The same ( value == null) is passed also in the code generated by the designer.

This thing is driving me nuts. Please can anyone help me deal with this?
Also if someone can tell me where exactly is the point of entry from the view to the database. Is it related to the model binder? because i wanted to check exactly what value is passed once i press the "submit" button.
Thank you.

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

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

发布评论

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

评论(1

酷到爆炸 2024-09-06 07:32:33

一般来说,所有验证内容都是在绑定值绑定之后起作用。正如您所理解的,不可能从像“asdvfvk”这样的字符串绑定日期时间值。因此,当绑定程序遇到此类错误时,它将其添加到 ModelState(查看 ModelState["DateOfBirth"].Errors[0].ErrorMessage),并绑定默认值。日期时间的默认值?为 null,所以这就是为什么您总是在 IsValid 方法中获取它。这很正常。
因此,正如您所看到的,如果您想检查日期是否大于其他日期,则日期验证是有意义的。如果输入字符串不正确,则进一步验证没有意义。

你能做什么?

第一种简单的方法 - 您可以像这样更正您的操作 正如

 [HttpPost]
        public ActionResult About(Person person, string dateOfBirth) {
            var birthdayAttribute = new BirthdayAttribute();
            if( !birthdayAttribute.IsValid(dateOfBirth)) {
                ModelState["DateOfBirth"].Errors.Clear();
                ModelState.AddModelError("DateOfBirth", birthdayAttribute.ErrorMessage);
            }
           .......
        }

您所看到的,有字符串 dateOfBirth,因此活页夹在绑定字符串值方面没有问题。但这不会让你的用户满意。

更好的方法 - 确保字符串在客户端 Javascript 中采用正确的格式。实际上,人们使用日期选择器控件来进行日期并自我感觉良好。

另外看看这里 http://forums.asp.net/t/1512140.aspx< /a>
特别是布拉德·威尔逊的回答。

Generally speaking all validation stuff is work after binder binded values. As you can understand it's not possible to bind dateTime value from string like "asdvfvk". So, when binder encounters with such an error it adds it to the ModelState (take a look at ModelState["DateOfBirth"].Errors[0].ErrorMessage), and binds default value. Default value for DateTime? is null, so that's why you always get it in IsValid method. It's normal.
So as you can see validation for date has sence if you whant to check for example if it's bigger then some other date. If input string is incorrect no further verification have sence.

What can you do?

First straightforward way - you can correct your action like this

 [HttpPost]
        public ActionResult About(Person person, string dateOfBirth) {
            var birthdayAttribute = new BirthdayAttribute();
            if( !birthdayAttribute.IsValid(dateOfBirth)) {
                ModelState["DateOfBirth"].Errors.Clear();
                ModelState.AddModelError("DateOfBirth", birthdayAttribute.ErrorMessage);
            }
           .......
        }

As you can see there is string dateOfBirth, so binder have no problems with binding string value. But this will not make your users happy.

The better way - ensure that string will be in correct format with client Javascript. Actualy people use date picker controls for dates and feel themselves good.

In addition take a look here http://forums.asp.net/t/1512140.aspx
Especialy Brad Wilson's answer.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文