2009-01-21 6 views
5

मैं एएसपी.नेट एमवीसी का उपयोग कर एक रीस्टफुल एपीआई के प्रोटोटाइप को कार्यान्वित कर रहा हूं और यहां और वहां की अजीब बग के अलावा, मैंने शुरुआत में सेट की गई सभी आवश्यकताओं को प्राप्त किया है, कॉलर्स X-HTTP-Method-Override कस्टम का उपयोग करने में सक्षम हैं HTTP विधि को ओवरराइड करने के लिए हेडर।क्या एएसपी.नेट एमवीसी में एक्स-एचटीटीपी-विधि-ओवरराइड को कार्यान्वित करना संभव है?

क्या मैं चाहता हूँ कि निम्नलिखित अनुरोध ...

GET /someresource/123 HTTP/1.1 
X-HTTP-Method-Override: DELETE 

... मेरी नियंत्रक विधि है कि कि कार्रवाई के लिए GET कार्यक्षमता के बजाय DELETE कार्यक्षमता लागू करता है (कि यह सोचते हैं के लिए रवाना किया जायेगा कार्रवाई को लागू करने के कई तरीके हैं, और वे अलग-अलग [AcceptVerbs] विशेषताओं के साथ चिह्नित हैं)। तो, निम्नलिखित दो तरीकों को देखते हुए, मैं ऊपर अनुरोध चाहते दूसरा एक के लिए भेजा जा करने के लिए होगा:

[ActionName("someresource")] 
[AcceptVerbs(HttpVerbs.Get)] 
public ActionResult GetSomeResource(int id) { /* ... */ } 

[ActionName("someresource")] 
[AcceptVerbs(HttpVerbs.Delete)] 
public ActionResult DeleteSomeResource(int id) { /* ... */ } 

अगर यह संभव हो सकता है किसी को भी पता है? और ऐसा करने के लिए कितना काम होगा ...?

उत्तर

5

में निर्मित होते हैं आप [AcceptVerbs] विशेषता का उपयोग करने में सक्षम नहीं होगा के रूप में है, क्योंकि यह अनुरोध के वास्तविक HTTP क्रिया से जुड़ा हुआ है। सौभाग्य से [AcceptVerbs] विशेषता बहुत सरल है; आप http://www.codeplex.com/aspnet/SourceControl/changeset/view/21528#266431 पर अपने लिए स्रोत देख सकते हैं।

संक्षेप में, सबक्लास AcceptsVerbsAttribute स्वीकार करता है और IsValidForRequest() विधि को ओवरराइड करता है। कार्यान्वयन निम्न जैसा होगा:

string incomingVerb = controllerContext.HttpContext.Request.Headers["X-HTTP-Method-Override"] ?? controllerContext.HttpContext.Request.Method; 
return Verbs.Contains(incomingVerb, StringComparer.OrdinalIgnoreCase); 
+0

मुझे AcceptVerbsAttribute से कोड को निकलना पड़ा और दुर्भाग्यवश इसे सील कर दिया गया है, लेकिन मेरा दृष्टिकोण पूरी तरह से काम करता है और अच्छा और सरल है, ऐसा लगता है कि आपको 300 अंक मिलते हैं! –

+0

हाय लेवी, हालांकि मेरा एएसपीनेट आईआईएस या एमवीसी डिलीट और पुट अनुरोध से इंकार कर रहा है, क्या इस काम को पाने के लिए वैसे भी है? मैंने अनुमति देने की कोशिश की: PUT, IIS में हटाएं हेडर को अनुमति दें लेकिन यह काम नहीं करेगा ... – DucDigital

+0

डक, मुझे पता है कि यह लंबे समय तक लंबा रहा है, लेकिन देखें कि वेबडाव इंस्टॉल है या नहीं। यदि यह है, तो इसे अनइंस्टॉल करें। अन्यथा, यह आपके PUT को रोक देगा और अनुरोधों को हटा देगा। –

0

X-HTTP-Method-Override एक कस्टम शीर्षलेख है और अधिकतर आपके वेब कंटेनर द्वारा समर्थित नहीं है।

आप एक वेब पेज से कर रहे हैं? यदि ऐसा है, तो आपको शायद XmlHttpRequestDELETE (या जो भी क्रिया आप चाहते हैं) के साथ उपयोग करना चाहिए। बेहतर अभी तक, आपके लिए भारी उठाने के लिए जेएस ढांचे का उपयोग करें।

+0

मैं इसे कॉल नहीं कर रहा हूं, मैं इसे कार्यान्वित कर रहा हूं ... और मैं कार्यान्वयन को कस्टम हेडर का समर्थन करना चाहता हूं। –

+0

मुझे समझ में नहीं आता है। यदि आप कार्यान्वयन को नियंत्रित करते हैं, तो क्यों आप धरती पर HTTP क्रिया का उपयोग नहीं करेंगे जिस तरह से इसे मानक क्रियाओं का उपयोग करके डिजाइन किया गया था? – Kevin

+2

दुर्भाग्यवश कुछ क्लाइंट, प्रॉक्सी और फ़ायरवॉल जीईटी या पोस्ट के अलावा क्रियाओं की अनुमति नहीं देते हैं, इसलिए कभी-कभी लोगों को पोस्ट के साथ प्राप्त करने और PUT के साथ नकली डिलीट करने में सक्षम होना चाहिए। यह थोड़ा लंगड़ा है, लेकिन अधिकांश रीस्टफुल सेवाएं इस हेडर का समर्थन करने लगती हैं। –

0

आप एक एक्शनफ़िल्टर बना सकते हैं जो OnActionExecuting लागू करता है, जो नियंत्रक कार्रवाई के पहले आग लगती है। इसके बाद आप अनुरोध हेडर से पूछताछ कर सकते हैं, और वर्तमान में X-HTTP-Method-Override हेडर के मान के आधार पर रीडायरेक्ट कर सकते हैं।

+0

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

1

आप Simply Restful Routing को देखा है? यह पहले से ही यह करता है।

संपादित फ़र, 2010 को जोड़ने के लिए: विधि ओवरराइड MVC 2.

+0

मुझे X-HTTP-Method-Override को लागू करने के बारे में कुछ भी नहीं दिखाई देता है और स्रोत का त्वरित स्कैन कुछ भी प्रकट नहीं करता है। क्या तुम इसके बारे में निश्चित हो? यदि ऐसा है तो क्या आप मुझे उस फ़ाइल में इंगित कर सकते हैं जिसमें इसे लागू किया गया है? चीयर्स! –

+0

एक्स-एचटीटीपी-विधि-ओवरराइड गैर-जीईटी/POST अनुरोधों का समर्थन करने के लिए एक व्यक्ति का डिज़ाइन है। बस आराम से रूटिंग एक और है। अलग डिजाइन, एक ही लक्ष्य। –

+0

मैं वास्तव में आरपीटी स्टाइल यूआरएल के साथ आरईएसटी को जोड़ना नहीं चाहता हूं (मैं एक या दूसरे से खुश हूं, लेकिन दोनों के संयोजन से बचना पसंद करूंगा) तो मुझे लगता है कि मैं कार्रवाई के मुकाबले हेडर विकल्प के साथ जाऊंगा बस आराम से डिजाइन के रूप में लिंक। –

3

लेवी का जवाब बहुत अच्छा है। साथ ही, मुझे लगता है कि यह भी फार्म संग्रह की जांच करता है कस्टम AcceptsVerbsAttribute में एक चेक जोड़ा है, तो आप बस हटाने को गति प्रदान करने के लिए एक छिपे हुए इनपुट (MVC 2 के Html.HttpMethodOverride(HttpVerbs.Delete) के समान) डाल सकते हैं।

<input name="X-HTTP-Method-Override" type="hidden" value="DELETE" /> 

बदलें करने के लिए incomingVerb काम:

string incomingVerb = controllerContext.HttpContext.Request.Headers["X-HTTP-Method-Override"] ?? controllerContext.HttpContext.Request.Form["X-HTTP-Method-Override"] ??controllerContext.HttpContext.Request.HttpMethod; 

इस दृष्टिकोण के साथ सावधान रहें! स्टीफन वाल्थर द्वारा related post देखें।

उम्मीद है कि यह किसी की सहायता करता है।

+0

सामग्री प्रकार के शीर्षलेख में इसे MIME प्रकार पैरामीटर के रूप में भेजने का एक और संभावित समाधान। – inf3rno

3

सम्मिलित फार्म करने के लिए:

<%= Html.HttpMethodOverride(HttpVerbs.Delete) %> 
2

यह बातचीत एक सा पुराना है, लेकिन मुझे लगता है मैं MVC 2 का उपयोग क्या पाया है साझा करना चाहते थे:

ब्राउज़रों का समर्थन दो HTTP क्रियाएं: प्राप्त और पोस्ट है, लेकिन एएसपी.नेट एमवीसी 2 आपको Html.HttpMethodOverride सहायक विधि का उपयोग करके पुट, गेट और डिलीट अनुकरण करने की अनुमति देता है। आंतरिक रूप से, यह एक एक्स-HTTP-विधि-ओवरराइड फ़ॉर्म फ़ील्ड में क्रिया भेजकर काम करता है। HttpMethodOverride के व्यवहार से प्रयोग किया जाता है नई छोटी क्रिया के रूप में जिम्मेदार बताते हैं [AcceptVerbs] और साथ ही विशेषता:

उदाहरण के लिए, कार्रवाई घोषणा:

[ActionName("someresource")] 
[HttpDelete] 
public ActionResult DeleteSomeResource() 

अपने GET अनुरोध एक्स है कि के लिए जिम्मेदारी लेनी चाहिए -एचटीटीपी-विधि-ओवरराइड हटाने के लिए सेट करें।

+0

न केवल फॉर्म फ़ील्ड में। शीर्षलेख या क्वेरी स्ट्रिंग में भी हो सकता है। विचार यह है कि HTTP विधि ओवरराइडिंग समर्थित है। +1 –

1

मुझे आश्चर्य है कि इसका अभी तक उल्लेख नहीं किया गया है, लेकिन एएसपी.नेट एमवीसी मूल रूप से एक्स-एचटीटीपी-विधि-ओवरराइड का समर्थन करता है और कम से कम संस्करण 2 से ऐसा कर रहा है। कस्टम कोड लिखने की कोई आवश्यकता नहीं है इससे निपटो।

यह निम्नलिखित तरीके से काम करते हैं:

अंदर AcceptVerbsAttribute (यह भी [HttpPut], [HttpPost], आदि के द्वारा प्रॉक्सी), वहाँ एक IsValidForRequest विधि है।

  • अधिभावी केवल पोस्ट अनुरोध में समर्थित है: कि विधि के अंदर, यह Request.GetHttpMethodOverride() है, जो निम्नलिखित शर्तों के साथ उचित ओवरराइड HTTP विधि रिटर्न के साथ जाँच करता है। अन्य सभी को नजरअंदाज कर दिया जाता है।
  • यदि एक्स-HTTP-विधि-ओवरराइड मान प्राप्त या पोस्ट है, तो इसे अनदेखा किया जाता है। यह समझ में आता है, क्योंकि आपको इन मानों के साथ कभी ओवरराइड करने की आवश्यकता नहीं होगी। 1) HTTP हैडर 2) फार्म शरीर 3) क्वेरी स्ट्रिंग

तुम सच में उत्सुक हैं, तो यहाँ है:

  • यह एक्स-HTTP-विधि-ओवरराइड इस प्राथमिकता में निम्नलिखित स्थानों में के लिए लग रहा है कैसे GetHttpMethodOverride() दिखता है (एमवीसी 3 के स्रोत कोड से):

    public static class HttpRequestExtensions { 
        internal const string XHttpMethodOverrideKey = "X-HTTP-Method-Override"; 
    
        public static string GetHttpMethodOverride(this HttpRequestBase request) { 
         if (request == null) { 
          throw new ArgumentNullException("request"); 
         } 
    
         string incomingVerb = request.HttpMethod; 
    
         if (!String.Equals(incomingVerb, "POST", StringComparison.OrdinalIgnoreCase)) { 
          return incomingVerb; 
         } 
    
         string verbOverride = null; 
         string headerOverrideValue = request.Headers[XHttpMethodOverrideKey]; 
         if (!String.IsNullOrEmpty(headerOverrideValue)) { 
          verbOverride = headerOverrideValue; 
         } 
         else { 
          string formOverrideValue = request.Form[XHttpMethodOverrideKey]; 
          if (!String.IsNullOrEmpty(formOverrideValue)) { 
           verbOverride = formOverrideValue; 
          } 
          else { 
           string queryStringOverrideValue = request.QueryString[XHttpMethodOverrideKey]; 
           if (!String.IsNullOrEmpty(queryStringOverrideValue)) { 
            verbOverride = queryStringOverrideValue; 
           } 
          } 
         } 
         if (verbOverride != null) { 
          if (!String.Equals(verbOverride, "GET", StringComparison.OrdinalIgnoreCase) && 
           !String.Equals(verbOverride, "POST", StringComparison.OrdinalIgnoreCase)) { 
           incomingVerb = verbOverride; 
          } 
         } 
         return incomingVerb; 
        } 
    } 
    
  • संबंधित मुद्दे

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