2013-07-11 20 views
6

मैं माइक्रोसॉफ्ट एएसपी.नेट वेब एपीआई का उपयोग कर रीस्टफुल सेवा बना रहा हूं।एएसपी.NET वेब एपीआई प्रतिक्रियाओं से HttpError को हटा रहा है

मेरी समस्या से संबंधित है HttpErrors कि वेब एपीआई कुछ गलत होने पर उपयोगकर्ता को वापस फेंकता है (उदाहरण के लिए 400 खराब अनुरोध या 404 नहीं मिला)।

समस्या यह है, कि मैं प्रतिक्रिया सामग्री में धारावाहिक HttpError प्राप्त करने के लिए, के रूप में यह कभी कभी बहुत अधिक जानकारी प्रदान करता है नहीं करना चाहते, इसलिए यह उदाहरण के लिए OWASP सुरक्षा नियमों का उल्लंघन,:

अनुरोध:

http://localhost/Service/api/something/555555555555555555555555555555555555555555555555555555555555555555555 

एक प्रतिक्रिया के रूप में, मैं निश्चित रूप से 400 मिलता है, लेकिन निम्न सामग्री की जानकारी के साथ:

{ 
"$id": "1", 
"Message": "The request is invalid.", 
"MessageDetail": "The parameters dictionary contains a null entry for parameter 'id' of non-nullable type 'System.Int32' for method 'MyNamespaceAndMethodHere(Int32)' in 'Service.Controllers.MyController'. An optional parameter must be a reference type, a nullable type, or be declared as an optional parameter." 
} 

इस तरह न केवल इंगित करता है कि मेरी WebServic ई ASP.NET वेबएपीआई प्रौद्योगिकी (जो कि बुरा नहीं है) पर आधारित है, लेकिन यह भी यह

मैं Global.asax

में IncludeErrorDetailPolicy सेट करने की कोशिश की मेरी नामस्थान, विधि के नाम, मानकों, आदि के बारे में कुछ जानकारी देता है
GlobalConfiguration.Configuration.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Never; 

हाँ, यह किसी भी तरह से अच्छा था, अब परिणाम में संदेश वितरण अनुभाग नहीं है, लेकिन फिर भी, मैं यह HttpError बिल्कुल प्राप्त नहीं करना चाहता हूं।

मैंने अपना कस्टम प्रतिनिधिमंडल भी बनाया, लेकिन यह 400 और 404 को भी प्रभावित करता है जो मैं स्वयं नियंत्रकों में उत्पन्न करता हूं, जो मैं नहीं करना चाहता हूं।

मेरा प्रश्न है: प्रतिक्रिया सामग्री से धारावाहिक HttpError से छुटकारा पाने के लिए कोई ठोस तरीका है? मैं चाहता हूं कि उपयोगकर्ता अपने बुरे अनुरोधों के लिए वापस आएं, प्रतिक्रिया कोड है।

उत्तर

1

कस्टम IHttpActionInvoker का उपयोग करने के बारे में क्या? असल में, आपको बस एक खाली HttpResponseMessage भेजना होगा।

public class MyApiControllerActionInvoker : ApiControllerActionInvoker 
{ 
    public override Task<HttpResponseMessage> InvokeActionAsync(HttpActionContext actionContext, System.Threading.CancellationToken cancellationToken) 
    { 
     var result = base.InvokeActionAsync(actionContext, cancellationToken); 

     if (result.Exception != null) 
     { 
      //Log critical error 
      Debug.WriteLine("unhandled Exception "); 

      return Task.Run<HttpResponseMessage>(() => new HttpResponseMessage(HttpStatusCode.InternalServerError)); 
     } 
     else if (result.Result.StatusCode!= HttpStatusCode.OK) 
     { 
      //Log critical error 
      Debug.WriteLine("invalid response status"); 

      return Task.Run<HttpResponseMessage>(() => new HttpResponseMessage(result.Result.StatusCode)); 
     } 


     return result; 
    } 
} 

Global.asax में

GlobalConfiguration.Configuration.Services.Replace(typeof(IHttpActionInvoker), new MyApiControllerActionInvoker()); 

एक अन्य महत्वपूर्ण बात यह है तुम कर सकते हो, जाल एपीआई से संबंधित नहीं है, अत्यधिक asp.net दूर करने के लिए है:

यहाँ एक बहुत ही बुनियादी उदाहरण है & आईआईएस HTTP शीर्षलेख। Here एक अच्छी व्याख्या है।

+0

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

+0

+1। ग्रेट रीड री: हेडर –

1

मेरा मानना ​​है कि संदेश हैंडलर का उपयोग करने का आपका दृष्टिकोण सही है क्योंकि वेब एपीआई पाइपलाइन में घटक की परवाह किए बिना, जो स्टेटस कोड को 4xx पर सेट करता है, संदेश हैंडलर प्रतिक्रिया निकाय को साफ़ कर सकता है। हालांकि, आप उन अन्य लोगों के बीच अंतर करना चाहते हैं जिन्हें आप स्पष्ट रूप से अन्य घटकों द्वारा निर्धारित किए गए बनाम सेट करते हैं। यहां मेरा सुझाव है और मैं मानता हूं कि यह थोड़ा हैकी है। यदि आपको कोई अन्य बेहतर समाधान नहीं मिलता है, तो इसे आज़माएं।

अपने ApiController कक्षाओं में, जब आप HttpResponseException फेंकते हैं, तो अनुरोध गुणों में ध्वज सेट करें।

Request.Properties["myexception"] = true; 
throw new HttpResponseException(...); 

संदेश हैंडलर में, संपत्ति की जांच करें और संपत्ति सेट होने पर प्रतिक्रिया निकाय को साफ़ न करें।

var response = await base.SendAsync(request, cancellationToken); 

if((int)response.StatusCode > 399 && !request.Properties.Any(p => p.Key == "myException")) 
    response.Content = null; 

return response; 

आप इस एक सा अच्छी तरह से HttpRequestMessage के लिए एक विस्तार विधि जोड़कर पैकेज कर सकते हैं ताकि न ApiController है और न ही संदेश हैंडलर हार्ड-कोडेड स्ट्रिंग "myException" कि मैं ऊपर का उपयोग के बारे में कुछ जानता है।

+0

यह निश्चित रूप से काम करेगा, लेकिन जैसा कि आपने कहा है, बल्कि दीर्घकालिक समाधान की तुलना में ठीक है। –

संबंधित मुद्दे