2017-02-17 2 views
2

クラスインスタンスをコントローラに送信し、そのクラスのプロパティがEnum型であるとします。Web api 2のオブジェクトパラメータの列挙型の検証

public class CoffeeController : ApiController 
{ 
    [HttpPost] 
    public async Task<IHttpActionResult> OrderAsync(Order request) 
    { 
     return Ok(); 
    } 
} 

public enum CoffeeType 
{ 
    Latte, 
    Mocha, 
    Espresso 
} 

public class Order 
{ 
    public CoffeeType Type { get; set; } 
    public string Name { get; set; } 
} 

要求の列挙型メンバーの名前にエラーがある場合、アプリケーションは例外をスローしません。代わりにデフォルトのenum値を使用します。

{"name":"Dan", 'type':"ocha"}=>{"Name":"Dan", "Type":"Latte"} 

これは私にとって奇妙なことです。 なぜこのような動作が使用されていますか?

エラーを発生させるエレガントな方法はありますか?

答えて

0

Brettが怒鳴ったように、ModelState.IsValidを使用するとModelStateにエラーが発生します。 あなたが好き、あなたのタイプのためのカスタムメディアフォーマッタを使用することができ、エラー投げるだけが必要な場合:

public class OrderJsonFormatter : BufferedMediaTypeFormatter 
    { 
     public OrderJsonFormatter() 
     { 
      SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/json")); 
     } 

     public override bool CanReadType(Type type) 
     { 
      var canRead = type == typeof(Order); 
      return canRead; 
     } 

     public override bool CanWriteType(Type type) 
     { 
      return false; 
     } 

     public override object ReadFromStream(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger) 
     { 
      return this.ReadFromStream(type, readStream, content, formatterLogger, CancellationToken.None); 
     } 

     public override object ReadFromStream(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger, CancellationToken cancellationToken) 
     { 
      using (var reader = new StreamReader(readStream)) 
      { 
       using (var jsonReader = new JsonTextReader(reader)) 
       { 
        var jsonSerializer = new JsonSerializer(); 

        if (type == typeof(Order)) 
        { 


         try 
         { 
          var entity = jsonSerializer.Deserialize<Order>(jsonReader); 
          return entity; 
         } 
         catch (Exception ex) 
         { 
         //log error here 
          throw; 
         } 
        } 

        return null; 
       } 
      } 
     } 


    } 

して登録する:

GlobalConfiguration.Configuration.Formatters.Insert(0, new OrderJsonFormatter()); 
0

それはあなたに検証を適用

public enum CoffeeType 
{ 
    Invalid = 0 
    Latte = 1, 
    Mocha = 2, 
    Espresso = 3 
} 
1

を列挙型は整数型に基づいているため、これを行いますので、彼らは常に値を持つことになります(値の型はnullにすることはできません)と0の使用がデフォルトになり、次の回避策モデル。 ActionFilterAttributeを作成し、それをパイプラインに配線するか、エンドポイントをそのパイプラインで飾ります。あなたはまた、検証を実行するための偉大なライブラリとしてFluentValidationをお勧めしますお勧めします。

の例を参考にしてください(例:this article)。