2010-03-19 5 views
5

Geerbte Eigenschaften und MetadataType scheint nicht mit Client-seitige Validierung in ASP.NET MVC zu arbeiten 2.MetadataType und Client-Validierung in ASP.NET MVC 2

Die Validierung unserer MetadataTypes arbeiten auf dem Server wie erwartet aber aus irgendeinem Grund erzeugt es nicht die passenden Client-Skripte dafür. Die clientseitige Validierung wird erwartungsgemäß für Eigenschaften mit den in der PersonView festgelegten DataAnnotations-Attributen ausgeführt, sodass ich weiß, dass die clientseitige Validierung aktiv ist und funktioniert. Weiß jemand, ob oder wie es behoben werden kann?

Hier ist, was wir haben:

public abstract class PersonView 
{ 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 
    public string Email { get; set; } 
    [Required] public string PhoneNumber { get; set; } 
    public string AddressLine1 { get; set; } 
    public string AddressLine2 { get; set; } 
    public string AddressZipCode { get; set; } 
    public string AddressCity { get; set; } 
    public string AddressCountry { get; set; } 
} 

[MetadataType(typeof(CustomerViewMetaData))] 
public class CustomerView : PersonView {} 

[MetadataType(typeof(GuestViewMetaData))] 
public class GuestView : PersonView {} 

public class GuestViewMetaData 
{ 
    [Required(ErrorMessage = "The guests firstname is required")] public string FirstName { get; set; } 
    [Required(ErrorMessage = "The guests lastname is required")] public string LastName { get; set; } 
} 

public class CustomerViewMetaData 
{ 
    [Required(ErrorMessage = "The customers firstname is required")] public string FirstName { get; set; } 
    [Required(ErrorMessage = "The customers lastname is required")] public string LastName { get; set; } 
    [Required(ErrorMessage = "The customers emails is required")] public string Email { get; set; } 
} 

Wie Sie sehen, es ist nichts Besonderes oder seltsam dort ... Kann es behoben werden? Ist es ein Fehler in ASP.NET MVC 2?

+0

Ich bin neugierig, hast du das jemals gelöst? –

+0

@SkippyFire: Schau dir meine Antwort an! –

Antwort

2

Nach einem Microsoft offiziellen dies ist ein Fehler in ASP.NET MVC 2. Ich erhielt den unten stehenden Link und obwohl das Szenario nicht genau das gleiche ist, scheint es das gleiche Problem zu sein. Soweit ich das beurteilen kann, hängt es mit den nicht geerbten Eigenschaften und dem DataAnnotations-Metadaten-Provider zusammen. Der Link sagt, sie werden versuchen, das Problem in ASP.NET MVC ist es zu spät 3.

Asp.net MVC 2 RC2: the client side validation does not work with overridden properties

+0

Ich bin froh, dass Sie das Problem gefunden haben. Danke für das Update! –

+0

@SkippyFire und @Kristoffer, gibt es Neuigkeiten darüber, ob dies bisher in irgendwelchen Versionen behoben wurde? –

+0

Wurde dies in v3 behoben? Nach meinen Tests scheint mir immer noch ein Problem zu bestehen. – Ahmad

0

Sind Sie sicher? Ich habe eine ASP.NET MVC 2-Site eingerichtet, wie Sie beschreiben, und ich habe clientseitige Validierung von erforderlichen und Regex-basierten Attributen, die gut funktioniert. Es funktioniert nicht mit meinem eigenen Validatoren arbeitet allerdings zur Zeit (die von Validation ableiten):

[MetadataType(typeof(AlbumMetadata))] 
public partial class Album {} 

public class AlbumMetadata { 
    [Required(ErrorMessage = "You must supply a caption that is at least 3 characters long.")] 
    [MinLength(3, ErrorMessage = "The caption must be at least {0} characters long.")] 
    [RegularExpression(@".{3,}")] 
    public string Caption { get; set; } 
} 

(MinLength bietet im Grunde eine offensichtliche Art und Weise zu sehen, was in der Regular Expression Attribute geschieht, die für die Prüfung hinzugefügt wurde)

ich habe folgendes dann meiner Meinung nach:

<script src="/Scripts/MicrosoftAjax.js" type="text/javascript"></script> 
<script src="/Scripts/MicrosoftMvcValidation.js" type="text/javascript"></script> 

<%= Html.ValidationSummary("Edit was unsuccessful. Please correct the errors and try again.") %> 
<% Html.EnableClientValidation(); %> 
<% using (Html.BeginForm()) {%> 
<fieldset> 
    <legend>Album details</legend> 
    <div class="form_row"> 
     <label for="Caption" class="left_label">Album caption:</label> 
     <%= Html.TextBox("Caption", Model.Caption, new { @class = "textbox" })%> 
     <%= Html.ValidationMessage("Caption", "*") %> 
     <div class="cleaner">&nbsp;</div> 
    </div> 
    <div class="form_row"> 
     <label for="IsPublic" class="left_label">Is this album public:</label> 
     <%= Html.CheckBox("IsPublic", Model.IsPublic) %> 
    </div> 
    <div class="form_row"> 
     <input type="submit" value="Save" /> 
    </div> 
</fieldset> 
<% } %> 

die dem Kunden unter den Formular-Tags (formatiert für Klarheit in der folgenden ausgegeben führt):

<script type="text/javascript"> 
//<![CDATA[ 
if (!window.mvcClientValidationMetadata) 
{ window.mvcClientValidationMetadata = []; } 
window.mvcClientValidationMetadata.push({ 
    "Fields":[ 
     {"FieldName":"Caption", 
     "ReplaceValidationMessageContents":false, 
     "ValidationMessageId":"Caption_validationMessage", 
     "ValidationRules":[ 
     {"ErrorMessage":"You must supply a caption that is at least 3 characters long.", 
      "ValidationParameters":{}, 
      "ValidationType":"required"}, 
     {"ErrorMessage":"The field Caption must match the regular expression \u0027.{3,}\u0027.", 
      "ValidationParameters":{"pattern":".{3,}"}, 
      "ValidationType":"regularExpression"}] 
     }], 
     "FormId":"form0","ReplaceValidationSummary":false}); 
//]]> 
</script> 
+0

Es ist schwer zu sagen, wenn ich nicht den anderen Teil der Album-Klasse habe, aber erben Sie wirklich von einer Basisklasse in Ihrem Album partially? Schau dir meine Antwort an. –

+0

@Kristoffer Ahl - Album ist Teil meines Entity Framework Datenmodells, also ja, es erbt definitiv etwas: 'public partially class Album: global :: System.Data.Objects.DataClasses.EntityObject' (aus der Datei Designer.cs) an die .edmx-Datei angehängt), und das enthält eine dekorierte Caption-Eigenschaft ('[EdmScalarPropertyAttribute (IsNullable = false)]' und '[DataMemberAttribute()]') –

1

Vielleicht zu beheben, aber das ist die Art, wie ich es geschafft, diese Fehler zu lösen.
Ich habe einen benutzerdefinierten Modellmetadatenanbieter erstellt, der von DataAnnotationsModelMetadataProvider erbt und die Methode CreateMetadata überschreibt. Das Problem ist, dass der Wert in containerType Parameter auf die Basisklasse zeigt statt auf geerbte Klasse verweist. Hier ist der Code

public class CustomModelMetadataProvider : DataAnnotationsModelMetadataProvider 
{ 
    protected override ModelMetadata CreateMetadata(
     IEnumerable<Attribute> attributes, 
     Type containerType, 
     Func<object> modelAccessor, 
     Type modelType, 
     string propertyName) 
    { 

     if (modelAccessor != null && containerType != null) 
     {     
      FieldInfo container = modelAccessor.Target.GetType().GetField("container"); 
      if (containerType.IsAssignableFrom(container.FieldType)) 
       containerType = container.FieldType; 
     } 

     var modelMetadata = base.CreateMetadata(attributes, containerType, modelAccessor, modelType, propertyName); 



     return modelMetadata; 
    } 
} 

Und schließlich haben wir diese kundenspezifische Metadaten-Anbieter in Global.asax bei Application_Start registrieren

ModelMetadataProviders.Current = new CustomModelMetadataProvider(); 

Sorry für mein Englisch!