3

私はVS2008 SP1、WCF Ria Service July 2009 CTPを使用しています。MetadataType が部分クラス モードでは機能しないことがわかりました。実際に何を見逃したのかわかりません。

仕事:-

public partial class Person
{
    private string _Name;

    [Required(AllowEmptyStrings=false, ErrorMessage="Name required entry")]
    [StringLength(3)]
    public string Name
    {
        set{_Name = value;}
        get{return _Name;}
    }
}

class Program
{
    static void Main(string[] args)
    {
        Person p = new Person { Name="123432" };
        List res = new List();
        Validator.TryValidateObject(p,new ValidationContext(p,null,null),
            res,true);
        if (res.Count > 0)
        {
            Console.WriteLine(res[0].ErrorMessage);
            Console.ReadLine();
        }
    }
}

うまくいかない

public partial class Person
{
    private string _Name;

    public string Name
    {
        set{_Name = value;}
        get{return _Name;}
    }
}

[MetadataType(typeof(PersonMetadata))]
public partial class Person
{
}


public partial class PersonMetadata
{
    [Required(AllowEmptyStrings=false, ErrorMessage="Name required entry")]
    [StringLength(3)]
    public string Name;
}

class Program
{
    static void Main(string[] args)
    {
        Person p = new Person { Name="123432" };
        List res = new List();
        Validator.TryValidateObject(p,new ValidationContext(p,null,null),
            res,true);
        if (res.Count > 0)
        {
            Console.WriteLine(res[0].ErrorMessage);
            Console.ReadLine();
        }
    }
}
4

3 に答える 3

10

編集:私はここで答えを見つけました:http://forums.silverlight.net/forums/p/149264/377212.aspx

検証する前に、メタデータクラスを手動で登録する必要があります。

TypeDescriptor.AddProviderTransparent(
            new AssociatedMetadataTypeTypeDescriptionProvider(typeof(Person), typeof(PersonMetadata)), typeof(Person));

        List<ValidationResult> res = new List<ValidationResult>();
        bool valid = Validator.TryValidateObject(p, new ValidationContext(p, null, null), res, true);

(元の答えは次のとおりです)

問題は特に部分クラスにあるのではなく、Validator.TryValidateObjectがMetaDataType属性を認識していないように見えることです。同じ問題があります。MVC2の組み込みの検証ではメタデータクラスが認識されますが、TryValidateObjectでは認識されません。

これらを参照してください: Validatorクラスを使用したDataAnnotationsの検証Validator.TryValidateObject を使用すると、検証が機能しません

ちなみに、必要かどうかはわかりませんが、メタデータクラスで見たすべての例では、各プロパティでデフォルトのget/setを使用しています。

[Required(AllowEmptyStrings=false, ErrorMessage="Name required entry")]
[StringLength(3)]
public string Name { get; set; }
于 2010-03-18T02:50:37.583 に答える
3

上記の回答をくれた Jeremy Gruenwald に感謝します...私はこれに完全に行き詰まりました。

このソリューションに基づいて標準の検証クラスを作成したかったのですが、メタデータ クラスの型を渡す必要はありませんでした。

これを実現するために、カスタム属性を参照してメタデータ クラス タイプを取得し、検証結果を返す前にそのクラスを登録する静的クラスを作成しました。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Linq;

namespace MyApp.Validation
{
    public static class EntityValidator
    {
        public static List<ValidationResult> Validate(object instance, bool validateAllProperties = true)
        {
            RegisterMetadataClass(instance);

            var validationContext = new ValidationContext(instance, null, null);
            var validationResults = new List<ValidationResult>();

            Validator.TryValidateObject(instance, validationContext, validationResults, validateAllProperties);

            return validationResults;
        }

        private static void RegisterMetadataClass(object instance)
        {
            var modelType = instance.GetType();
            var metadataType = GetMetadataType(modelType);

            if (metadataType != null) 
            {
                TypeDescriptor.AddProviderTransparent(new AssociatedMetadataTypeTypeDescriptionProvider(modelType, metadataType), modelType);
            }
        }

        private static Type GetMetadataType(Type type)
        {
            var attribute = (MetadataTypeAttribute)type.GetCustomAttributes(typeof (MetadataTypeAttribute), true).FirstOrDefault();
            return attribute == null ? null : attribute.MetadataClassType;
        }
    }
}

使用方法は次のように簡単です。

var errors = EntityValidator.Validate(myEntity);
于 2015-05-08T15:37:17.983 に答える