2011-07-13 13 views
10

नियंत्रक प्रकार पर कार्रवाई 'सूचकांक' के लिए वर्तमान अनुरोध 'UsersController' निम्न कार्रवाई तरीकों के बीच अस्पष्ट है। Mvc.ActionResult PostUser (Int32, Models.SimpleUser) प्रकार Controllers.UsersController परपैरामीटर अलग होने के बावजूद इन दो कार्रवाइयों को संदिग्ध क्यों माना जाता है? System.Web.Mvc.ActionResult PostUser (Models.SimpleUser) पर प्रकार Controllers.UsersController System.Web:

हो रहा है जब मैं प्रपत्र मूल्यों के साथ website.com/users/ पोस्ट करने की कोशिश।

जब कोई आईडी नहीं है (website.com/users/) मैं एक नया उपयोगकर्ता बनाना चाहता हूं, जब कोई आईडी है (उदाहरण के लिए उपयोगकर्ता/51) मैं चाहता हूं कि वह उस उपयोगकर्ता को अपडेट करे, तो कैसे मैं इसे इन दो कार्रवाइयों के बीच अंतर बताता हूं?

[HttpPost] 
    [ActionName("Index")] 
    public ActionResult PostUser(SimpleUser u) 
    { 

     return Content("User to be created..."); 
    } 

    [HttpPost] 
    [ActionName("Index")] 
    public ActionResult PostUser(int id, SimpleUser u) 
    { 

     return Content("User to be updated..."); 
    } 

यहाँ MapRoute है:

यहाँ दो कार्यों हैं

routes.MapRoute(
     "Users", 
     "users/{id}", 
     new { controller = "Users", action = "Index" } 
    ); 
+0

मैंने http: // stackoverflow पर एक ही प्रश्न पूछा।कॉम/प्रश्न/6479631/क्यों-कैंट-एएसपी-नेट-एमवीसी-अंतर-बीच-दो-क्रिया-जब-वे-अलग-अलग -0- – KallDrexx

उत्तर

8

मुख्य समस्या यह है कि आपके दो क्रिया विधियों के बीच कुछ अस्पष्टता है, क्योंकि मॉडल बाइंडिंग रूटिंग कॉन्फ़िगरेशन को रद्द करने में मदद नहीं करती है। आपका वर्तमान रूटिंग बस इंडेक्स विधि को इंगित करता है।

आपके पास अभी भी एक ही यूआरएल हो सकता है, लेकिन यह आपके कार्यों को अलग-अलग नाम देने में मददगार होगा और फिर कुछ नए मार्ग लागू करें।

[HttpPost] 
public ActionResult Create(SimpleUser u) 
{ 
    return Content("User to be created..."); 
} 

[HttpPost] 
public ActionResult Edit(int id, SimpleUser u) 
{ 
    return Content("User to be updated..."); 
} 

और फिर अपने मार्ग में कोशिश

routes.MapRoute(
    "UserEdit", 
    "users/{id}", 
    new { controller = "Users", action = "Edit", 
     httpMethod = new HttpMethodConstraint("POST") }); 

routes.MapRoute(
    "UserCreate", 
    "users", 
    new { controller = "Users", action = "Create", 
     httpMethod = new HttpMethodConstraint("POST") }); 

मार्गों केवल घटनाओं पोस्ट करने के लिए, जिसका अर्थ है आप अभी भी उसी रास्ते पर अपने GET तरीकों के लिए कुछ मार्ग में जोड़ सकते हैं विवश कर दिया जाएगा। जैसे किसी सूची या कुछ के लिए।

+0

मुझे उत्सुकता है कि यह/{id} का पता क्यों नहीं लगाता है और इसलिए आईडी को ले जाने वाली क्रिया का चयन करें। मुझे लगता है कि मैं उलझन में हूं क्योंकि अधिकांश भाषाओं में मैंने पैरामीटर सूची का उपयोग किया है, विधि के नाम के हस्ताक्षर का उतना ही हिस्सा है। – BigOmega

+2

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

-1

बेहतर होगा कि उपयोग करने पर विचार बना सकते हैं और प्राप्त करने के लिए आप क्या चाहते हैं कार्यों को संपादित करेंगे। आम तौर पर सभी उपयोगकर्ताओं को सूचीबद्ध करने के लिए इंडेक्स का उपयोग किया जा सकता है (आपके मामले में)। जिस समस्या का आप सामना कर रहे हैं, उसके बारे में यह उत्पन्न हो रहा है क्योंकि ऐसा कोई मार्ग नहीं है जो पैरामीटर के रूप में कोई आईडी न ले।

+0

ऐसा नहीं कर सकते हैं, मैं आवश्यक idempotent के साथ एक विश्वसनीय API बना रहा हूँ यूआरएल, प्राप्त/पुट/डिलीट सभी एक ही/उपयोगकर्ता/[आईडी] यूआरएल का उपयोग करेंगे और POST/उपयोगकर्ता/(आईडी के साथ) का उपयोग करेगा, वास्तव में अभी मैं सृजन के लिए POST का उपयोग कर रहा हूं, लेकिन अब आपको यह विचार मिल गया है । साथ ही, यह उत्तर की तुलना में एक बेहतर टिप्पणी हो सकती है क्योंकि यह प्रश्न का उत्तर नहीं देती है। – BigOmega

0

आपको दो अलग-अलग क्रिया नामों के जरिए अपने तरीकों को अलग करना होगा।

एक विश्वसनीय API रखने के लिए आप क्या कर सकते हैं अपनी RouteHandler कक्षा बनाना है जो रूटिंग को बदल देगा, इस पर निर्भर करता है कि {id} मान मौजूद है या नहीं। RouteHandler वर्ग सरल है:

using System.Web.Mvc; 
using System.Web.Routing; 

    public class MyRouteHandler : IRouteHandler 
    { 
    public IHttpHandler GetHttpHandler(RequestContext requestContext) 
    { 
     var routeData = requestContext.RouteData; 
     if (routeData.Values("id").ToString() == "0" /* our default invalid value */) 
     { 
     var action = routeData.Values("action"); 
     routeData.Values("action") = action + "Add"; 
     } 
     var handler = new MvcHandler(requestContext); 
     return handler; 
    } 
    } 

इसके बाद, Global.asax.cs में RegisterRoutes() संशोधित इस प्रकार है:

public static void RegisterRoutes(RouteCollection routes) 
    { 
     routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); 

     AreaRegistration.RegisterAllAreas(); 

     routes.Add("Default", new Route("{controller}/{action}/{id}", 
      new RouteValueDictionary(
       new { controller = "Home", 
         action = "Index", 
         id = "0" /* our default invalid value */ }), 
      new MyRouteHandler())); 
    } 

अंत में, अपने ऐड विधि "IndexAdd" के लिए ActionName विशेषता बदल जाते हैं। जब अनुरोध आईडी के बिना आता है, तो डिफ़ॉल्ट अमान्य मान प्रदान किया जाएगा, जो आपके रूट जोड़ेंडलर को आपकी "जोड़ें" विधि में विधि बदलने के लिए चेतावनी देगा।

काउंसेलोरबेन

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

  • कोई संबंधित समस्या नहीं^_^