5

継承されたプロパティと MetadataType は、ASP.NET MVC 2 のクライアント側の検証では機能しないようです。

MetadataTypes の検証はサーバー上で期待どおりに機能しますが、何らかの理由で適切なクライアント スクリプトが生成されません。クライアント側の検証は、PersonView に設定された DataAnnotations 属性を持つプロパティに対して期待どおりに開始されるため、クライアント側の検証がアクティブであり、機能することがわかります。修正できるかどうか、または修正できる方法を知っている人はいますか?

ここに私たちが持っているものがあります:

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; }
}

ご覧のとおり、そこには空想や奇妙なものは何もありません.修正できますか? ASP.NET MVC 2 のバグですか?

4

3 に答える 3

2

Microsoft の公式によると、これは ASP.NET MVC 2 のバグです。以下のリンクが提供されました。シナリオはまったく同じではありませんが、同じ問題のようです。私が知る限り、継承されたプロパティと DataAnnotations モデル メタデータ プロバイダーに関連しています。リンクには、ASP.NET MVC 3 で問題の修正を試みると書かれています。

Asp.net MVC 2 RC2: クライアント側の検証はオーバーライドされたプロパティでは機能しません

于 2010-03-31T07:34:43.980 に答える
1

手遅れかもしれませんが、これが私がこのバグを解決する方法です。DataAnnotationsModelMetadataProviderから継承し、 CreateMetadataメソッドをオーバーライド
するカスタムモデルメタデータプロバイダーを作成しました。問題は、containerTypeパラメーターの値が、継承されたクラスではなく、基本クラスを指していることです。これがコードです

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;
    }
}

そして最後に、このカスタムメタデータプロバイダーをApplication_StartのGlobal.asaxに登録する必要があります

ModelMetadataProviders.Current = new CustomModelMetadataProvider();

英語でごめんなさい!

于 2011-01-28T18:07:40.260 に答える
0

本気ですか?あなたが説明したようにASP.NET MVC 2サイトをセットアップしました.必要な属性と正規表現ベースの属性の両方のクライアント側の検証が正常に機能します。ただし、現時点では、(ValidationAttribute から派生する) 私自身のバリデーターでは機能しません。

[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基本的に、テストのために追加された正規表現属性で何が起こっているかを確認するためのより明白な方法を提供します)

次に、私の見解では次のことを考えています。

<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>
<% } %>

その結果、クライアントのフォーム タグの下に次のように出力されます (わかりやすくするために書式設定されています)。

<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>
于 2010-03-26T11:44:20.970 に答える