2016-11-16 5 views
3

JsonPropertyを使用して名前を上書きするモデルがいくつかありますが、ModelStateで検証エラーが発生すると問題が発生します。例:ModelState.Errorsで[JsonProperty( "name")]を使用する

class MyModel 
{ 
    [JsonProperty("id")] 
    [Required] 
    public string MyModelId {get;set;} 
} 

class MyModelController 
{ 
    public IHttpActionResult Post([FromBody] MyModel model) 
    { 
     if (!ModelState.IsValid) 
     { 
      return HttpBadRequest(ModelState); 
     } 

     /* etc... */ 
    } 
} 

上記の投稿は、正確ではないエラーThe MyModelId field is required.を返します。私たちはこれをThe id field is required.と言いたいと思います。 [DataMember(Name="id")]を使用しようとしましたが、同じ結果が得られます。

質問1: [必須]属性ごとに独自のエラーメッセージを提供する以外に、ModelStateエラーでC#プロパティ名ではなくJSONプロパティ名を表示する方法はありますか?

- 更新 -

私はこれで遊んでとカスタムプロパティ名を使用して、エラーメッセージを再作成するため、「日曜大工」方法を見つけてきました。私は実際にこれを行うには、組み込みの方法があります望んでいるが、これは仕事をしているようだ...

https://gist.github.com/Blackbaud-JasonTremper/b64dc6ddb460afa1698daa6d075857e4

質問2:ModelState.Keyは<parameterName>.<reflectedProperty>構文と一致すると仮定することができますこれが真実でないかもしれない場合がありますか?

質問3:JSONのパラメータ名があることではなく、[DataMember]または[JsonProperty]属性に反射を経由して検索することが期待されているかを決定する簡単な方法はありますか?

答えて

2

DisplayName属性を試しましたか?

displayname attribute vs display attribute

また、あなたは[Required]属性にエラーメッセージを割り当てることができます。

[Required(ErrorMessage = "Name is required")]

+0

を。しかし、あなたがリンクしていることによると、[表示]プロパティは仕事をしました(多分それはあなたが意味するものです)。ありがとう! – jt000

0

また、私はこの問題に直面し、私は私のWebAPIのに合わせて、あなたのリンクからいくつかのコードを変更しました。 modelStateには、モデルの変数名である古いキーとJsonプロパティ名も格納されます。

  1. まず、ValidateModelStateFilter
  2. は、コントローラのメソッド

の上にフィルタのソースコード[ValidateModelStateFilter]を追加フィルタを作成します。私は、[表示名]試すんでしたし、それが動作しませんでした

public class ValidateModelStateFilter : ActionFilterAttribute 
{ 
    public override void OnActionExecuting(HttpActionContext actionContext) 
    { 
     var descriptor = actionContext.ActionDescriptor; 
     var modelState = actionContext.ModelState; 

     if (descriptor != null) 
     { 
      var parameters = descriptor.GetParameters(); 

      var subParameterIssues = modelState.Keys 
               .Where(s => s.Contains(".")) 
               .Where(s => modelState[s].Errors.Any()) 
               .GroupBy(s => s.Substring(0, s.IndexOf('.'))) 
               .ToDictionary(g => g.Key, g => g.ToArray()); 

      foreach (var parameter in parameters) 
      { 
       var argument = actionContext.ActionArguments[parameter.ParameterName]; 

       if (subParameterIssues.ContainsKey(parameter.ParameterName)) 
       { 
        var subProperties = subParameterIssues[parameter.ParameterName]; 
        foreach (var subProperty in subProperties) 
        { 
         var propName = subProperty.Substring(subProperty.IndexOf('.') + 1); 
         var property = parameter.ParameterType.GetProperty(propName); 
         var validationAttributes = property.GetCustomAttributes(typeof(ValidationAttribute), true); 

         var value = property.GetValue(argument); 

         modelState[subProperty].Errors.Clear(); 
         foreach (var validationAttribute in validationAttributes) 
         { 
          var attr = (ValidationAttribute)validationAttribute; 
          if (!attr.IsValid(value)) 
          { 
           var parameterName = GetParameterName(property); 
           // modelState.AddModelError(subProperty, attr.FormatErrorMessage(parameterName)); 
           modelState.AddModelError(parameterName, attr.FormatErrorMessage(parameterName)); 
          } 
         } 
        } 
       } 


      } 
     } 

    } 

    private string GetParameterName(PropertyInfo property) 
    { 
     var dataMemberAttribute = property.GetCustomAttributes<DataMemberAttribute>().FirstOrDefault(); 
     if (dataMemberAttribute?.Name != null) 
     { 
      return dataMemberAttribute.Name; 
     } 

     var jsonProperty = property.GetCustomAttributes<JsonPropertyAttribute>().FirstOrDefault(); 
     if (jsonProperty?.PropertyName != null) 
     { 
      return jsonProperty.PropertyName; 
     } 

     return property.Name; 
    } 
} 
+0

AspNetCoreのバージョンがありますか?ありがとう –

関連する問題