2015-03-03 14 views
9

WebAPI v2.2 kullanıyorum ve WebAPI'yi [FromBody] özniteliğini kullanarak bir nesnenin üzerine JSON serisini çıkartıyorum. deserialisation hedef sınıfı böyle bir iç yöntem üzerinde bir [OnDeserialized] niteliğine sahiptir: Bu yöntem içinde koduyla bir sorun olduğunda bir gerçeği biliyorumWebAPI C'deki istek serileştirme sırasında yakalama istisnası #

[OnDeserialized] 
internal void OnDeserialisedMethod(StreamingContext context) { 
    // my method code 
} 

, ben adım attı ettik ve onu buldum. Benim için sorun hiç bir istisna olmamam. Ne olur bu yöntem dışarı atlanır ve istisna göz ardı ediliyor gibi görünüyor. Denetleyicimin eylemi aranıyor ve bu seri hale getirme yöntemi doğru şekilde yürütülemediğinden hedef nesnem doğru şekilde doldurulmuyor.

Soruma; WebAPI'da seri hale getirme sırasında oluşan bir özel durumu nasıl yakalayabilirim?

+0

http://www.asp.net/web-api/overview/error-handling/web-api-global-error-handling –

+0

Bu web sayfasında önerildiği gibi yaptım ama hala seçmiyor istisna kadar? ExceptionHandler sınıfından türetme ve 'config.Services.Replace (typeof (IExceptionHandler), yeni Exceptions.MyExceptionHandler());' – Anupheaus

+0

ile kayıt yaptırmak Aslında istisnayı yakalarlar, ancak istediğim istisnayı değil. Hedef sınıfımın uygun şekilde doldurulmadığı istisnayı yakalar, yine de OnDeserialized yönteminden herhangi bir istisna görmüyor. Denetleyici eylem yöntemine girmeden ÖNCE hataları yakalamam gerekiyor ve bu bir sorun gibi görünüyor, göz ardı ediliyor gibi görünüyor. – Anupheaus

cevap

9

(olarak ModelState'i kontrol eden ve serileştirme hataları meydana geldiğinde bir istisna atar. Ancak, bunun yalnızca serileştirme istisnaları içermeyebileceğine dikkat edin; bu, Select ifadesindeki somut istisna türünü belirterek ayarlanabilir.

public class ValidModelsOnlyFilter : ActionFilterAttribute 
{ 
    public override void OnActionExecuting(HttpActionContext actionContext) 
    { 
     if (actionContext.ModelState.IsValid) 
     { 
      base.OnActionExecuting(actionContext); 
     } 
     else 
     { 
      var exceptions = new List<Exception>(); 

      foreach (var state in actionContext.ModelState) 
      { 
       if (state.Value.Errors.Count != 0) 
       { 
        exceptions.AddRange(state.Value.Errors.Select(error => error.Exception)); 
       } 
      } 

      if (exceptions.Count > 0) 
       throw new AggregateException(exceptions); 
     } 
    } 
} 

Bu filtrenin global bir kapsamda bağlanmasını öneririm. Serpilestirme istisnalarını görmezden gelmek için neden iyi olması gerektiğine gerçekten inanamıyorum.

1

Denetleyicinizin içine ModelState.IsValid'u kontrol edebilirsiniz. "OnDeserialisedMethod" bir istisna atarsa ​​(veya başka bir model doğrulama başarısız olursa) yanlış olacaktır, her şey başarılı olursa doğru olacaktır.

2

Tam olarak aynı soruna sahiptim ve birilerinin bir çözüm sunması ümidiyle sorunuzu işaretledim. ModelState'i kullanarak, JSON modelinde bazı doğrulamaları yeniden yazmayı düşündüm, ama sadece işe yarıyor, aslında basit ve gayet başarılı. Modeli değiştirmek zorunda değildim, sadece kontrolörler.

benim denetleyicileri biri gerekirse StdResponse (Bu durumda, örneğin) detayları ile yanıt vermek için kullanılan sınıf olmaktan Benim kod: Ben bir filtre yazdım

[HttpPost] 
public StdResponse Test([FromBody]StdRequest request) 
{ 
    if (ModelState.IsValid) 
    { 
     //Work on the data from the request... 
    } 
    else 
    { 
     //Retrieve the exceptions raised during deserialization 
     var errors = ModelState.SelectMany(v => v.Value.Errors.Select(e => e.Exception)); 

     List<String> messages = new List<string>(); 

     foreach (Exception e in errors) 
     { 
      messages.Add(e.GetType().ToString() + ": " + e.Message); 
     } 

     return new StdResponse(exchangeVersion, "null", ExecutionResponse.WithError("StdRequest invalid", messages)); 
    } 
}