2016-07-21 5 views
2

プロパティの上にrequired属性を持つ単純モデルがあるとします。ASP.NET RC2 - ModelStateはコレクションの要素を検証しません

public class User 
{ 
    [Required] 
    string Name {get;set;} 
    string Surname {get;set;} 
} 

私がPOST/PUTすると、UserとNameのインスタンスが1つだけ空の場合は、かなりうまく動作します。 ModelStateが無効で、エラーが含まれています。

オブジェクトのPOST/PUTコレクションと、その一部に名前が空であり、ModelStateが有効で、検証エラーが含まれていないものがあります。

あなたはそれに何が間違っているのか、それはなぜコレクションだけに関係するのか教えてください。 1つのオブジェクトにリレーション1つがある場合、同じ動作に気付きました。このオブジェクト内のコレクションは、ModelStateによっても検証されません。

必要なフィールドを手動で検証する必要はなく、自動的に動作するはずです。

+0

を追加する必要がありプロパティ。 – Takahiro

答えて

-1

あなたは検証はプロパティレベルである、あなたは、モデルの中にコレクションを置くことができ、回避策があるのActionFilter

public class ModelStateValidActionFilter : IAsyncActionFilter 
{ 
    public Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next) 
    { 
     // Validate ICollection 
     if (context.ActionArguments.Count == 1 && context.ActionArguments.First().Value.GetType().IsListType()) 
     { 
      foreach (var arg in (IList)context.ActionArguments.First().Value ) 
      { 
       var parameters = arg.GetType().GetProperties(); 
       foreach (var parameter in parameters) 
       { 
        var argument = context.ActionArguments.GetOrDefault(parameter.Name); 
        EvaluateValidationAttributes(parameter, argument, context.ModelState); 
       } 
      } 
     } 

     if (context.ModelState.IsValid) 
     { 
      return next(); 
     } 
     context.Result = new BadRequestObjectResult(context.ModelState); 
     return Task.CompletedTask; 
    } 

    private void EvaluateValidationAttributes(PropertyInfo parameter, object argument, ModelStateDictionary modelState) 
    { 
     var validationAttributes = parameter.CustomAttributes; 
     foreach (var attributeData in validationAttributes) 
     { 
      var attributeInstance = parameter.GetCustomAttribute(attributeData.AttributeType); 
      var validationAttribute = attributeInstance as ValidationAttribute; 
      if (validationAttribute != null) 
      { 
       var isValid = validationAttribute.IsValid(argument); 
       if (!isValid) 
       { 
        modelState.AddModelError(parameter.Name, validationAttribute.FormatErrorMessage(parameter.Name)); 
       } 
      } 
     } 
    } 

を作成し、MVCのオプションに

services.AddMvc() 
    .AddMvcOptions(opts => 
    { 
     opts.Filters.Add(new ModelStateValidActionFilter()); 
    } 
+1

これは、コレクションの検証の問題をどのように解決しますか? – Thomas

+0

コレクションがプロパティの場合、IValidatableObjectを実装して検証することはできますが、ルートコレクションを検証する方法はないようです。検証は 'プロパティレベル'の属性にのみ適用されます。 – Takahiro

+0

私はそれが自動的に動作しないとは思わない。 Addressをプロパティとして持ち、Addresに空のrequiredプロパティがあるモデルegUserをネストした場合、エラーが発生します。コレクションに何かがあるはずです... – Ellbar

関連する問題