2015-03-03 9 views
9

में अनुरोध deserialization के दौरान अपवाद कैप्चर करें मैं WebAPI v2.2 का उपयोग कर रहा हूं और मुझे वेब से आईपीओआई को [FromBody] विशेषता का उपयोग करके किसी ऑब्जेक्ट पर deserialise करने के लिए मिल रहा है। deserialisation का लक्ष्य वर्ग एक आंतरिक विधि पर एक [OnDeserialized] विशेषता, इस तरह है:वेबएपीआई सी #

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

मैं एक तथ्य यह है कि इस विधि के अंदर कोड के साथ एक समस्या है के लिए पता है, मैं इसके माध्यम से कदम रखा है और मिल गया। मेरे लिए समस्या यह है कि मुझे कोई अपवाद नहीं है। क्या होता है यह विधि बाहर निकल जाती है और अपवाद को अनदेखा किया जाता है। मेरी नियंत्रक कार्रवाई को बुलाया जाता है और मेरा लक्ष्य ऑब्जेक्ट उचित रूप से पॉप्युलेट नहीं होता है क्योंकि यह क्रमबद्धता विधि सही ढंग से निष्पादित नहीं की गई है।

मेरा प्रश्न है; मैं WebAPI में deserialisation के दौरान होने वाले अपवाद को कैप्चर कैसे कर सकता हूं?

+0

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

+0

मैंने उस वेब पेज पर सुझाए गए अनुसार किया है लेकिन यह अभी भी नहीं उठाता है अपवाद अप? अपवाद हैंडलर क्लास से प्राप्त करना और 'config.Services.Replace (टाइपऑफ (IExceptionHandler), नया अपवाद। MyExceptionHandler()) के साथ पंजीकरण करना; ' – Anupheaus

+0

वे वास्तव में अपवाद पकड़ते हैं, लेकिन अपवाद नहीं चाहते हैं। यह अपवाद को पकड़ता है जहां मेरा लक्ष्य वर्ग उचित रूप से पॉप्युलेट नहीं होता है, फिर भी यह ऑनडिसेरियलाइज्ड विधि से कोई अपवाद नहीं देख रहा है। नियंत्रक कार्रवाई विधि में प्रवेश करने से पहले मुझे त्रुटियों को पकड़ने की आवश्यकता है और यह यहां एक मुद्दा प्रतीत होता है, उन्हें केवल अनदेखा किया जाता है। – Anupheaus

उत्तर

9

मैं एक फ़िल्टर लिखा है (के रूप में विभिन्न टिप्पणियों में सुझाया गया है) जो मॉडलस्टेट की जांच करता है और सीरियलाइजेशन त्रुटियां होने पर अपवाद फेंकता है। हालांकि सावधान रहें, इसमें केवल क्रमिकरण अपवाद नहीं हो सकते हैं - जिसे Select कथन में ठोस अपवाद प्रकार निर्दिष्ट करके समायोजित किया जा सकता है।

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); 
     } 
    } 
} 

मैं इस फ़िल्टर को वैश्विक दायरे पर बाध्य करने का सुझाव देता हूं। मैं वास्तव में यह नहीं समझ सकता कि deserialization अपवादों को नजरअंदाज करना क्यों ठीक होना चाहिए।

1

आप अपने नियंत्रक के अंदर ModelState.IsValid देख सकते हैं। यदि "OnDeserialisedMethod" एक अपवाद फेंकता है (या कोई अन्य मॉडल सत्यापन विफल रहता है) तो यह झूठा होगा, यदि सबकुछ सफल होता है तो यह सच होगा।

2

मुझे बिल्कुल वही समस्या थी और उम्मीद में आपके प्रश्न को बुकमार्क किया गया कि कोई समाधान प्रदान करेगा। मैंने सोचा कि मॉडलस्टेट का उपयोग जेएसओएन मॉडल में कुछ मान्यताओं को फिर से लिखना, लेकिन यह वास्तव में काम करता है, वास्तव में यह सरल और बहुत अच्छा किया जाता है। मुझे मॉडल को संशोधित करने की ज़रूरत नहीं थी, केवल नियंत्रक।

मेरी नियंत्रकों में से एक, StdResponse (उदाहरण के लिए, इस मामले में) यदि आवश्यक हो तो विवरण के साथ प्रतिक्रिया प्रदान करने के लिए इस्तेमाल किया जा रहा से वर्ग मेरे कोड:

[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)); 
    } 
} 
संबंधित मुद्दे