2011-04-28 17 views
6

पर HTTP क्रियाओं को सीमित करना प्रत्येक कार्रवाई के लिए उपलब्ध HTTP क्रियाओं को सीमित करना एक अच्छा अभ्यास है? मेरा कोड [HttpGet], [HttpPost], [HttpPut], या [HttpDelete] प्रत्येक क्रिया को सजाने के बिना क्लीनर है, लेकिन यह भी कम मजबूत या सुरक्षित हो सकता है। मुझे यह कई ट्यूटोरियल या उदाहरण कोड में नहीं देखा जाता है, जब तक कि क्रिया स्पष्ट रूप से आवश्यक न हो, जैसे दो "बनाएं" क्रियाएं हों, जहां जीईटी संस्करण एक नया फॉर्म लौटाता है और POST संस्करण एक नया रिकॉर्ड सम्मिलित करता है।प्रत्येक क्रिया

+0

:

public class AccountController : Controller { protected override IActionInvoker CreateActionInvoker() { return new HttpMethodPrefixedActionInvoker(); } public ActionResult GetLogOn() { ... } public ActionResult PostLogOn(LogOnModel model, string returnUrl) { ... } public ActionResult GetLogOff() { ... } public ActionResult GetRegister() { ... } public ActionResult PostRegister(RegisterModel model) { ... } [Authorize] public ActionResult GetChangePassword() { ... } [Authorize] public ActionResult PostChangePassword(ChangePasswordModel model) { ... } public ActionResult GetChangePasswordSuccess() { ... } } 

ध्यान दें कि इस कार्रवाई के नाम, जो अभी भी कर रहे हैं LogOn, LogOff, Register परिवर्तन नहीं करता है, आदि

कोड यह हो सकता है कि एक बेहतर तरीका चारों ओर एक और तरीका होगा, जो कस्टम गुण बनाते हैं जो उन क्रियाओं से इनकार करते हैं जिन्हें आप नहीं चाहते हैं। कभी कोशिश नहीं की, बस कह रहा है :-) – goenning

उत्तर

3

व्यक्तिगत तौर पर मैं RESTful conventions सम्मान करते हैं और प्राप्त क्रियाएं हैं जो इस प्रकार सर्वर पर किसी भी राज्य को संशोधित नहीं के अलावा HTTP क्रिया निर्दिष्ट करने के लिए कोशिश की जरूरत नहीं है उन्हें किसी भी HTTP क्रिया के साथ बुलाया जा सकता है।

0

आप HttpGet, अन्य सभी को निर्दिष्ट करने के लिए आप की क्या ज़रूरत है

+0

क्या इसका मतलब है कि निर्दिष्ट नहीं होने पर HttpGet डिफ़ॉल्ट रूप से है? –

+1

यह "ज़रूरत" का सवाल नहीं है, लेकिन "चाहिए"। यदि किसी चीज को अपडेट करने के लिए एक क्रिया का उपयोग किया जाता है (उदा। AJAX POST से), तो आपको इसे '[HttpPost]' के साथ चिह्नित करने की आवश्यकता नहीं है, लेकिन ऐसा लगता है कि यह एक अच्छा विचार होगा। – MikeWyatt

1

हां, मेरा मानना ​​है कि यह केवल आपके द्वारा नियंत्रित होने वाली उचित HTTP विधि को सीमित करने के लिए एक अच्छा अभ्यास है, यह आपके सिस्टम से खराब अनुरोध रखेगा, संभावित हमलों की प्रभावशीलता को कम करेगा, आपके कोड के दस्तावेज़ीकरण में सुधार करेगा ,, एक RESTful डिजाइन को लागू आदि

हाँ, का उपयोग कर [HttpGet], [HttpPost] .. गुण आपके कोड को पढ़ने के लिए कठिन है, खासतौर से भी [OutputCache], [Authorize] जैसे अन्य विशेषताओं का उपयोग, आदि बना सकते हैं

मैं का उपयोग एक कस्टम IActionInvoker के साथ एक छोटी सी चाल, गुणों का उपयोग करने के बजाय मैं HTTP विधि को वें ई कार्रवाई विधि का नाम, उदाहरण के लिए:

using System; 
using System.Collections.Generic; 
using System.Web.Mvc; 

public class HttpMethodPrefixedActionInvoker : ControllerActionInvoker { 

    protected override ActionDescriptor FindAction(ControllerContext controllerContext, ControllerDescriptor controllerDescriptor, string actionName) { 

     var request = controllerContext.HttpContext.Request; 

     string httpMethod = request.GetHttpMethodOverride() 
     ?? request.HttpMethod; 

     // Implicit support for HEAD method. 
     // Decorate action with [HttpGet] if HEAD support is not wanted (e.g. action has side effects) 

     if (String.Equals(httpMethod, "HEAD", StringComparison.OrdinalIgnoreCase)) 
     httpMethod = "GET"; 

     string httpMethodAndActionName = httpMethod + actionName; 

     ActionDescriptor adescr = base.FindAction(controllerContext, controllerDescriptor, httpMethodAndActionName); 

     if (adescr != null) 
     adescr = new ActionDescriptorWrapper(adescr, actionName); 

     return adescr; 
    } 

    class ActionDescriptorWrapper : ActionDescriptor { 

     readonly ActionDescriptor wrapped; 
     readonly string realActionName; 

     public override string ActionName { 
     get { return realActionName; } 
     } 

     public override ControllerDescriptor ControllerDescriptor { 
     get { return wrapped.ControllerDescriptor; } 
     } 

     public override string UniqueId { 
     get { return wrapped.UniqueId; } 
     } 

     public ActionDescriptorWrapper(ActionDescriptor wrapped, string realActionName) { 

     this.wrapped = wrapped; 
     this.realActionName = realActionName; 
     } 

     public override object Execute(ControllerContext controllerContext, IDictionary<string, object> parameters) { 
     return wrapped.Execute(controllerContext, parameters); 
     } 

     public override ParameterDescriptor[] GetParameters() { 
     return wrapped.GetParameters(); 
     } 

     public override object[] GetCustomAttributes(bool inherit) { 
     return wrapped.GetCustomAttributes(inherit); 
     } 

     public override object[] GetCustomAttributes(Type attributeType, bool inherit) { 
     return wrapped.GetCustomAttributes(attributeType, inherit); 
     } 

     public override bool Equals(object obj) { 
     return wrapped.Equals(obj); 
     } 

     public override int GetHashCode() { 
     return wrapped.GetHashCode(); 
     } 

     public override ICollection<ActionSelector> GetSelectors() { 
     return wrapped.GetSelectors(); 
     } 

     public override bool IsDefined(Type attributeType, bool inherit) { 
     return wrapped.IsDefined(attributeType, inherit); 
     } 

     public override string ToString() { 
     return wrapped.ToString(); 
     } 
    } 
} 
संबंधित मुद्दे