वेब एपीआई रूटिंग - एपीआई / {कंट्रोलर} / {एक्शन} / {आईडी} "डिसफंक्शंस" एपीआई / {कंट्रोलर} / {आईडी}


94

मेरे पास Global.asax में डिफ़ॉल्ट रूट है:

 RouteTable.Routes.MapHttpRoute(
         name: "DefaultApi",
         routeTemplate: "api/{controller}/{id}",
         defaults: new { id = System.Web.Http.RouteParameter.Optional }
         );

मैं एक विशिष्ट कार्य को लक्षित करने में सक्षम होना चाहता था, इसलिए मैंने एक और मार्ग बनाया:

RouteTable.Routes.MapHttpRoute(
         name: "WithActionApi",
         routeTemplate: "api/{controller}/{action}/{id}",
         defaults: new { id = System.Web.Http.RouteParameter.Optional }
         );

इसलिए, मेरे नियंत्रक में, मेरे पास है:

    public string Get(int id)
    {
        return "object of id id";
    }        

    [HttpGet]
    public IEnumerable<string> ByCategoryId(int id)
    {
        return new string[] { "byCategory1", "byCategory2" };
    }

कॉल करने .../api/records/bycategoryid/5से मुझे जो चाहिए वो मिलेगा। हालाँकि, कॉलिंग .../api/records/1मुझे त्रुटि देगा

अनुरोध से मेल खाते कई कार्य पाए गए: ...

मैं समझता हूं कि ऐसा क्यों है - मार्ग केवल वही परिभाषित करते हैं जो URL मान्य होते हैं, लेकिन जब यह कार्य मिलान की बात आती है, तो दोनों Get(int id)और ByCategoryId(int id)मेल खाते हैं api/{controller}/{id}, जो कि रूपरेखा को भ्रमित करता है।

फिर से काम करने के लिए डिफ़ॉल्ट एपीआई मार्ग प्राप्त करने के लिए मुझे क्या करने की आवश्यकता है, और एक को साथ रखें {action}? मैंने RecordByCategoryIdControllerडिफ़ॉल्ट एपीआई मार्ग से मेल करने के लिए नामांकित एक अलग नियंत्रक बनाने का सोचा , जिसके लिए मैं अनुरोध करूंगा .../api/recordbycategoryid/5। हालांकि, मुझे लगता है कि एक "गंदा" (इस प्रकार असंतोषजनक) समाधान होना चाहिए। मैंने इस पर जवाब के लिए देखा है और {action}इस मुद्दे का उल्लेख करने के साथ मार्ग का उपयोग करने पर कोई ट्यूटोरियल नहीं है ।

जवाबों:


104

रूट इंजन उसी क्रम का उपयोग करता है जैसे आप उसमें नियम जोड़ते हैं। एक बार जब यह पहला मिलान नियम हो जाता है, तो यह अन्य नियमों की जांच करना बंद कर देगा और नियंत्रक और कार्रवाई की खोज करने के लिए इसे ले जाएगा।

तो आपको चाहिए:

  1. अपने विशिष्ट नियमों को अपने सामान्य नियमों (जैसे डिफ़ॉल्ट) से आगे रखें, जिसका अर्थ है कि RouteTable.Routes.MapHttpRouteपहले "WithActionApi" का उपयोग करें, फिर "DefaultApi"।

  2. defaults: new { id = System.Web.Http.RouteParameter.Optional }अपने "WithActionApi" नियम के पैरामीटर को हटा दें क्योंकि एक बार id वैकल्पिक होने के बाद, url जैसे "/ api / {part1} / {part2}" कभी भी "DefaultApi" में नहीं जाएगा।

  3. रूट इंजन जो दर्ज करने के लिए कार्रवाई करने के लिए अपने "DefaultApi" में एक नामित कार्रवाई जोड़ें। अन्यथा एक बार जब आप अपने नियंत्रक में एक से अधिक कार्य करते हैं, तो इंजन को यह पता नहीं चलेगा कि किसका उपयोग करना है और "एकाधिक कार्यों को अनुरोध से मेल खाते हैं:"। फिर इसे अपने गेट विधि से मेल खाने के लिए, एक ActionNameAttribute का उपयोग करें ।

तो आपका मार्ग इस प्रकार होना चाहिए:

// Map this rule first
RouteTable.Routes.MapRoute(
     "WithActionApi",
     "api/{controller}/{action}/{id}"
 );

RouteTable.Routes.MapRoute(
    "DefaultApi",
    "api/{controller}/{id}",
    new { action="DefaultAction", id = System.Web.Http.RouteParameter.Optional }
);

और आपका नियंत्रक:

[ActionName("DefaultAction")] //Map Action and you can name your method with any text
public string Get(int id)
{
    return "object of id id";
}        

[HttpGet]
public IEnumerable<string> ByCategoryId(int id)
{
    return new string[] { "byCategory1", "byCategory2" };
}

1
मैंने ऊपर सलाह की कोशिश की और सब कुछ उम्मीद के मुताबिक काम करता है। उस "गुप्त" के लिए बहुत बहुत धन्यवाद।
मिकेल कारुसो

आपके उत्तर में बिंदु 2 पर, यदि idवैकल्पिक है तो URL जैसा रूट /api/{part1}/{part2}अभी भी चल सकता है DefaultApiयदि मार्ग के लिए कोई मिलान कार्रवाई नहीं मिली है WithActionApi। कृपया मुझे सुधारें अगर मैं गलत हूं।
orad

यदि मुझे एपीआई / {कंट्रोलर} / {एक्शन} चाहिए तो क्या होगा। आईडी के बिना। अगर कोई और उसी मुद्दे का सामना कर रहा है। WebApiConfig के बारे में भूल जाओ। विशेषता रूटिंग के बारे में पढ़ें।
अहसान्त

40

आप अपनी समस्या को Att रूटिंग रूटिंग की सहायता से हल कर सकते हैं

नियंत्रक

[Route("api/category/{categoryId}")]
public IEnumerable<Order> GetCategoryId(int categoryId) { ... }

Jquery में यू.आर.आई.

api/category/1

मार्ग विन्यास

using System.Web.Http;

namespace WebApplication
{
    public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            // Web API routes
            config.MapHttpAttributeRoutes();

            // Other Web API configuration not shown.
        }
    }
}

और आपकी डिफ़ॉल्ट रूटिंग डिफ़ॉल्ट कन्वेंशन-आधारित रूटिंग के रूप में काम कर रही है

नियंत्रक

public string Get(int id)
    {
        return "object of id id";
    }   

Jquery में यू.आर.आई.

/api/records/1 

मार्ग विन्यास

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        // Attribute routing.
        config.MapHttpAttributeRoutes();

        // Convention-based routing.
        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );
    }
}

अधिक जानकारी के लिए लेख की समीक्षा करें रूटिंग और ऑनवेंशन-आधारित रूटिंग यहाँ और यह


भगवान का जवाब। लेकिन हम सभी के लिए नहीं जोड़ सकते हैं, एपीआई / {नियंत्रक} / {क्रिया} / {आईडी} के साथ-साथ एपीआई / {नियंत्रक} / आईडी}?
करीम

रूटिंग रूटिंग निश्चित रूप से समस्या को हल करती है। एक महत्वपूर्ण बिंदु: वेब एपीआई 2 से पहले, वेब एपीआई परियोजना टेम्पलेट्स ने इस तरह कोड उत्पन्न किया: संरक्षित शून्य Application_Start () {WebApiConfig.Register (GlobalConfiguration.Configuration); } यदि विशेषता रूटिंग सक्षम है, तो यह कोड एक अपवाद फेंक देगा। यदि आप विशेषता रूटिंग का उपयोग करने के लिए एक मौजूदा वेब एपीआई परियोजना को अपग्रेड करते हैं, तो इस कॉन्फ़िगरेशन कोड को निम्न में अपडेट करना सुनिश्चित करें: संरक्षित शून्य Application_Start () {GlobalConfiguration.Configure (WebApiConfig.Register); }
डेब

0

इसे इस्तेमाल करे।

public class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        // Web API configuration and services

        var json = config.Formatters.JsonFormatter;
        json.SupportedMediaTypes.Add(new System.Net.Http.Headers.MediaTypeHeaderValue("application/json"));
        config.Formatters.Remove(config.Formatters.XmlFormatter);

        // Web API routes
        config.MapHttpAttributeRoutes();

        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{action}/{id}",
            defaults: new { id = RouteParameter.Optional , Action =RouteParameter.Optional }

        );
    }
}

0

संभावित कारण यह भी हो सकता है कि आपको ApiController से नियंत्रक विरासत में नहीं मिला है। मुझे समझने में थोड़ा समय लगा।


0

मार्गों को अलग करने के लिए, एक बाधा जोड़ने की कोशिश करें जो आईडी संख्यात्मक होनी चाहिए:

RouteTable.Routes.MapHttpRoute(
         name: "DefaultApi",
         routeTemplate: "api/{controller}/{id}",
         constraints: new { id = @"\d+" }, // Only matches if "id" is one or more digits.
         defaults: new { id = System.Web.Http.RouteParameter.Optional }
         );  
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.