2011-12-22 9 views
9

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

मैं क्या पढ़ा है/अध्ययन/कोशिश की

MVC विशेषताओं (HttpGet, HttpPost, आदि) मुझे एक ही नाम साझा करने के लिए कई कार्यों के साथ एक नियंत्रक की अनुमति है, लेकिन वे अभी भी विभिन्न विधि होनी चाहिए हस्ताक्षर।

रूटिंग मॉड्यूल में रूट बाधाएं एमवीसी में आने से पहले और परिणामस्वरूप मुझे 4 स्पष्ट मार्ग मिलेंगे, और फिर भी व्यक्तिगत रूप से नामित नियंत्रक कार्यों की आवश्यकता होगी।

ASP.NET MVC AcceptVerbs and registering routes

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

http://iwantmymvc.com/rest-service-mvc3


आवश्यकताओं/लक्ष्य

एक उदाहरण वस्तु के लिए
  1. एक मार्ग हस्ताक्षर, MVC चार मुख्य Http क्रिया को संभालने के लिए आशा की जाती है: मिलता है, पोस्ट, डाल, DELETE।

    context.MapRoute("Api-SingleItem", "items/{id}", 
        new { controller = "Items", action = "Index", id = UrlParameter.Optional } 
    ); 
    
  2. यूआरआई एक आईडी पैरामीटर पारित नहीं किया जाता है, तो एक कार्रवाई POST और PUT संभाल चाहिए।

    public JsonResult Index(Item item) { return new JsonResult(); } 
    
  3. एक आईडी पैरामीटर यूआरआई के लिए पारित किया जाता है, तो केवल एक कार्रवाई GET और DELETE संभाल चाहिए।

    public JsonResult Index(int id) { return new JsonResult(); } 
    

प्रश्न

मैं एक से अधिक कार्रवाई प्रत्येक एक अद्वितीय http क्रिया का जवाब (एक ही नाम और विधि हस्ताक्षर साझा करने) कैसे हो सकता है। वांछित उदाहरण:

[HttpGet] 
public JsonResult Index(int id) { /* _repo.GetItem(id); */} 

[HttpDelete] 
public JsonResult Index(int id) { /* _repo.DeleteItem(id); */ } 

[HttpPost] 
public JsonResult Index(Item item) { /* _repo.addItem(id); */} 

[HttpPut] 
public JsonResult Index(Item item) { /* _repo.updateItem(id); */ } 

उत्तर

10

रीस्टफुल कॉल के लिए, कार्रवाई का कोई मतलब नहीं है, क्योंकि आप केवल HTTP विधियों से अलग होना चाहते हैं। तो यह चाल एक स्थिर क्रिया नाम का उपयोग करना है, ताकि नियंत्रक पर विभिन्न विधियां केवल उन HTTP विधि में भिन्न हों जो वे स्वीकार करते हैं।

जबकि MVC framework provides a solution for specifying action names, इसे और अधिक संक्षेप और आत्म-समझाया जा सकता है।

एक विशेष गुण RESTful तरीकों को निर्दिष्ट (यह एक विशेष कार्य के नाम के लिए मेल खाता है) के लिए प्रयोग किया जाता है:

public sealed class RestfulActionAttribute: ActionNameSelectorAttribute { 
    internal const string RestfulActionName = "<<REST>>"; 

    public override bool IsValidName(ControllerContext controllerContext, string actionName, MethodInfo methodInfo) { 
     return actionName == RestfulActionName; 
    } 
} 

नियंत्रकों HTTP विधि के साथ संयोजन में इसका इस्तेमाल जिम्मेदार बताते हैं:

हम इसे इस तरह हल
public class MyServiceController: Controller { 
    [HttpPost] 
    [RestfulAction] 
    public ActionResult Create(MyEntity entity) { 
     return Json(...); 
    } 

    [HttpDelete] 
    [RestfulAction] 
    public ActionResult Delete(Guid id) { 
     return Json(...); 
    } 

    [HttpGet] 
    [RestfulAction] 
    public ActionResult List() { 
     return Json(...); 
    } 

    [HttpPut] 
    [RestfulAction] 
    public ActionResult Update(MyEntity entity) { 
     return Json(...); 
    } 
} 

और आदेश उन नियंत्रकों सफलतापूर्वक बाध्य करने में, हम कस्टम मार्गों स्थिर कार्रवाई नाम से beforementionned विशेषता से उपयोग करते हैं (जो एक ही समय में भी यूआरएल अनुकूलित करने के लिए अनुमति देते हैं):

routes.MapRoute(controllerName, pathPrefix+controllerName+"/{id}", new { 
    controller = controllerName, 
    action = RestfulActionAttribute.RestfulActionName, 
    id = UrlParameter.Optional 
}); 

ध्यान दें कि जहां तक ​​मैं कह सकता हूं, आपकी सभी आवश्यकताओं को आसानी से इस दृष्टिकोण से पूरा किया जा सकता है; एक विधि को कई HTTP विधियों को स्वीकार करने के लिए आपके पास एक विधि पर एकाधिक [HttpXxx] विशेषताएँ हो सकती हैं। कुछ स्मार्ट (एर) मॉडलबिन्डर के साथ जोड़ा गया यह बहुत शक्तिशाली है।

+0

शायद मुझे आपके उत्तर में कुछ याद आ रही है, लेकिन यह समझ में नहीं आता है। आपके उदाहरण में, प्रत्येक क्रिया का एक अलग नाम और एक अलग हस्ताक्षर होता है। मैं अनिवार्य रूप से एक ही विधि हस्ताक्षर के साथ 4 अलग-अलग क्रियाएं करने की कोशिश कर रहा हूं, प्रत्येक एक अलग http क्रिया का जवाब देता है। उन्हें अलग-अलग कार्य करने की आवश्यकता है क्योंकि उनमें से कुछ को प्राधिकरण की आवश्यकता होगी, अन्य लोग नहीं करेंगे। अद्यतन देखें। –

+0

@ one.beat.consumer: यहां बिंदु यह है कि विधि का नाम * अप्रासंगिक * है, क्योंकि वे सभी एक ही क्रिया नाम से मेल खाते हैं "<>" जो मार्ग के माध्यम से स्थिर रूप से सेट है। इसलिए आपके पास एक मार्ग पर कई विधियों (और आराम नियंत्रक) हो सकते हैं, और आपके पास "समान" क्रियाएं हो सकती हैं (भले ही उनके पास अलग-अलग विधि नाम हों) जो आपके समाधान ए से मेल खाते हैं, या आपके पास एकाधिक HTTP हो सकते हैं प्रति विधि विधियों यदि आप पसंद करते हैं जो आपका समाधान बी होगा, और आप फिट बैठकर इन समाधानों को भी मिश्रण कर सकते हैं। – Lucero

+0

@ one.beat.consumer: (पिछली टिप्पणी में स्थान से बाहर निकलें) ध्यान दें कि प्राधिकरण विधि स्तर पर नहीं किया गया है, न कि कार्रवाई स्तर पर, ताकि यदि आप '[प्राधिकरण]' विशेषता जोड़ते हैं तो यह ठीक काम करेगा क्रिया क्रियाओं में से कुछ। – Lucero

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