2010-04-24 31 views
2

这是我第一个关于堆栈溢出的问题。 我需要帮助,我正在处理ASP.NET MVC2项目期间遇到的问题。 我应该注意到,我对MVC设计比较陌生,所以请承担我的无知。 这里有: 我有一个常规的表格,其中显示了一个人的各种细节。其中之一是“出生日期”。我的看法是这样的ASP.NET MVC 2的“值”在IsValid覆盖的DataAnnotation属性中传递为空,当提交的日期不正确时

<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 =“.....”)]等属性,也不会显示自定义消息。显示的消息是从db返回的消息,即“值'32/4/1967'对于DateOfBirth无效”。我试图在代码周围输入一些断点,并发现日期不正确时,属性中的“值”始终为空,但如果日期格式正确,则始终会获取值。在设计器生成的代码中也传递相同的值(值=​​= null)。

这件事让我发疯。请任何人都可以帮我处理这个问题吗? 另外,如果有人能告诉我从视图到数据库的入口点究竟在哪里。它与模型联编程序有关吗?因为我想要确认一旦按下“提交”按钮时,通过了什么值。 谢谢。

回答

1

一般来说,所有验证内容都是在绑定器绑定值之后工作的。正如你可以理解的那样,不可能像“asdvfvk”那样绑定来自字符串的dateTime值。所以,当binder遇到这样的错误时,它将它添加到ModelState中(查看ModelState [“DateOfBirth”] .Errors [0] .ErrorMessage),并绑定默认值。 DateTime的默认值?为空,所以这就是为什么你总是使用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); 
      } 
      ....... 
     } 

正如你可以看到有串出生日期,所以粘结剂具有约束力的字符串值没有问题。但这不会让你的用户开心。

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

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

+0

非常感谢您澄清“问题”的根源在模型出价中,以及您的建议。我读链接,也发现这个答案http://stackoverflow.com/questions/1538873/how-to-replace-the-default-modelstate-error-message-in-asp-net-mvc-2。 我想保持在我的领域模型(也没有javascript可用)的验证。我想我必须阅读更多关于模型出价并覆盖其默认行为。虽然你的答案不能解决我的问题,但我检查我的问题,因为你指出了正确的方向。任何建议在哪里看? – goldenelf2 2010-04-26 01:00:42

+0

那么,默认的活页夹行为是好的。我认为来自微软的人有一些理由让它像这样工作:)验证将保留在您的域模型中。 Actualy ModelState将无效,直到 a。用户将输入正确格式的所有字符串(活页夹责任) b。所有的验证都没有问题(validatros责任,在领域模型中提出) Binder为你做了一份大工作。实际上,他为你做了你想要在验证器中做的事情。你希望日期格式正确 - 但它已经通过活页夹完成了。没有理由再做一次。 – 2010-04-26 02:45:03

+0

用户将收到消息,他输入的字符串格式不正确,然后他会以正确的格式输入它 - 而且,作为程序员,您可以确定,如果您期待DateTime - 活页夹将使用户输入字符串至极可以被解析为DateTime。这一切都在服务器上完成。 JavaScript有唯一的目的 - 帮助更快地形成正确格式的用户输入。但是,如果客户端上的JavaScript关闭 - 它不会改变,因为活页夹会使用户做正确的事情(否则用户将会消失)。 – 2010-04-26 03:00:37

相关问题