2

这是我关于堆栈溢出的第一个问题。我需要帮助解决我目前正在处理的 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' 对 DateOfBirth 无效。”。我尝试在代码周围输入一些断点,发现当日期不正确时,属性中的“值”始终为空,但如果日期格式正确,则始终获取值。设计器生成的代码中也传递了相同的 (value == null)。

这件事快把我逼疯了。请问有人可以帮我处理这个吗?另外,如果有人可以告诉我从视图到数据库的确切入口点在哪里。它与模型绑定器有关吗?因为我想在按下“提交”按钮后准确检查传递的值。谢谢你。

4

1 回答 1

1

一般来说,所有验证内容都是在绑定绑定值之后工作的。正如您所理解的,无法从“asdvfvk”之类的字符串中绑定 dateTime 值。因此,当 binder 遇到此类错误时,它会将其添加到 ModelState(查看 ModelState["DateOfBirth"].Errors[0].ErrorMessage),并绑定默认值。日期时间的默认值?是空的,所以这就是为什么你总是在 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,因此 binder 绑定字符串值没有问题。但这不会让您的用户满意。

更好的方法 - 确保字符串与客户端 Javascript 的格式正确。实际上,人们使用日期选择器控件来控制日期并感觉自己很好。

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

于 2010-04-25T18:12:22.450 回答