वेब एप में अनुरोध से मेल खाने वाली एकाधिक कार्रवाइयां पाई गईं


243

जब मैं 2 "गेट" विधियों को करने का प्रयास करता हूं तो मुझे यह त्रुटि मिलती रहती है

कई कार्य पाए गए जो अनुरोध से मेल खाते हैं: वेबपी

मैं स्टैक पर इस बारे में इसी तरह के अन्य प्रश्नों को देख रहा हूं, लेकिन मुझे यह नहीं मिला।

मेरे पास 2 अलग-अलग नाम हैं और "HttpGet" विशेषता का उपयोग कर रहे हैं

[HttpGet]
public HttpResponseMessage Summary(MyVm vm)
{
    return null;
}

[HttpGet]
public HttpResponseMessage FullDetails()
{
    return null;
}

जवाबों:


485

आपका रूट मैप शायद कुछ इस प्रकार है:

routes.MapHttpRoute(
name: "API Default",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional });

लेकिन एक ही http विधि के साथ कई कार्य करने के लिए आपको मार्ग के माध्यम से अधिक जानकारी के साथ वेबपीआई प्रदान करने की आवश्यकता है:

routes.MapHttpRoute(
name: "API Default",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional });

ध्यान दें कि अब रूटटेम्पलेट में एक क्रिया शामिल है। अधिक जानकारी यहाँ: http://www.asp.net/web-api/overview/web-api-rout-and-actions/rout-in-aspnet-web-api

अपडेट करें:

ठीक है, अब जब मुझे लगता है कि मैं समझता हूं कि आप यहाँ हैं तो इस पर एक और कदम उठाना चाहिए:

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

उदाहरण के लिए आपके दो तरीकों को चालू किया जा सकता है:

public HttpResponseMessage Get()
{
    return null;
}

public HttpResponseMessage Get(MyVm vm)
{
    return null;
}

आप MyVm ऑब्जेक्ट में किस तरह का डेटा पास कर रहे हैं? यदि आप यूआरआई के माध्यम से बस चर पास करने में सक्षम हैं, तो मेरा सुझाव है कि वह मार्ग जा रहा है। अन्यथा, आपको अनुरोध के शरीर में ऑब्जेक्ट भेजने की आवश्यकता होगी और वह एक जीईटी करते समय आपके बहुत HTTP नहीं है (हालांकि यह काम करता है, बस [FromBody] infront of MyVm) का उपयोग करें।

उम्मीद है कि यह दिखाता है कि आपके पास कार्रवाई नाम या यहां तक ​​कि [HttpGet] विशेषता का उपयोग किए बिना एक ही नियंत्रक में कई GET तरीके हो सकते हैं।


क्या एक तरह से या किसी अन्य को करने के कोई फायदे हैं? यदि मैं द्वितीयक करता हूं तो मुझे प्रत्येक विधि पर Http क्रिया करनी होगी? क्या वह बड़ी वापसी है?
चोबो 2

3
क्या कोई दूसरे पर लाभ उठाता है या नहीं यह वास्तव में आपकी परियोजना पर निर्भर करता है। यदि आप एक RESTful एपीआई का निर्माण कर रहे हैं, तो आप HTTP सम्मेलनों (GET, POST, PUT, DELETE ...) का उपयोग करना चाहेंगे। इस मामले में रूटिंग कोड का पहला ब्लॉक जाने का तरीका है, लेकिन आप एपीआई के माध्यम से उजागर होने वाली हर इकाई के लिए एक अलग नियंत्रक चाहते हैं। आपके विधि नामों के आधार पर, मैं यह अनुमान लगा रहा हूं कि ऐसा नहीं है इसलिए अधिक वर्णनात्मक रूटिंग का उपयोग करें। जब आपके मार्ग में वह क्रिया शामिल है जिसे आप स्पष्ट रूप से प्रत्येक विधि पर http विशेषता रखना चाहते हैं।
जेड

1
@ chobo2 नियंत्रक के भीतर नामित विधियों का उपयोग क्यों न करें? GetSummary (MyVm wm) और GetDetails ()
Jed

1
आपके उत्तर के लिए धन्यवाद, बस मुझे यह पता लगाने में मदद की कि रूट रिज़ॉल्यूशन काम क्यों नहीं कर रहा था, हालांकि मेरे दोनों कार्यों के अलग-अलग नाम थे। मैं वास्तव में उलझन में हूं कि सिर्फ डिफ़ॉल्ट व्यवहार क्यों नहीं है (यानी वेबपिकंफिग.कैंस में डिफ़ॉल्ट रूट टेम्पलेट क्यों नहीं है "{कार्रवाई}")!
तेजस शर्मा

1
@bruno यदि आप उन क्षेत्रों का उपयोग कर रहे हैं, तो आप इस तरह से 'admin' विशिष्ट APIs जोड़ सकते हैं जैसे कि AdminAreaRegademy में stackoverflow.com/a/9849011/16940
Simon_Weaver

67

वेब एपीआई 2 के रूप में अद्यतन करें।

अपनी WebApiConfig.cs फ़ाइल में इस API कॉन्फिग के साथ:

public static void Register(HttpConfiguration config)
{
    //// Web API routes
    config.MapHttpAttributeRoutes(); //Don't miss this

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

आप हमारे कंट्रोलर को इस तरह से रूट कर सकते हैं:

[Route("api/ControllerName/Summary")]
[HttpGet]
public HttpResponseMessage Summary(MyVm vm)
{
    rturn null;
}

[Route("api/ControllerName/FullDetails")]
[HttpGet]
public HttpResponseMessage FullDetails()
{
    return null;
}

जहां नियंत्रकनाम आपके नियंत्रक का नाम है ("नियंत्रक" के बिना)। यह आपको ऊपर विस्तृत मार्ग के साथ प्रत्येक कार्रवाई करने की अनुमति देगा।

आगे पढ़ने के लिए: http://www.asp.net/web-api/overview/web-api-rout-and-actions/attribute-rout-in-web-api-2


मुझे वास्तव में यह समाधान पसंद आया। मेरा डिफ़ॉल्ट मार्ग अभी भी वही है और मेरे पास अपवादों के लिए "अपवाद" मार्ग है
Leandro De Mello Fagundes

आप url EX: [मार्ग ("api / कंट्रोलरनेम / सारांश / {vm}") में मापदंडों को भी मैप कर सकते हैं
nulltron

15

वेब एपीआई में (डिफ़ॉल्ट रूप से) तरीकों को HTTP विधि और मार्ग मूल्यों के संयोजन के आधार पर चुना जाता है ।

MyVmएक जटिल वस्तु की तरह दिखता है, शरीर से फ़ॉर्मैटर द्वारा पढ़ा जाता है, इसलिए आपके पास मार्ग डेटा के संदर्भ में दो समान विधियां हैं (क्योंकि उनमें से किसी के पास मार्ग से कोई पैरामीटर नहीं है) - जो डिस्पैचर के लिए असंभव बनाता है ( IHttpActionSelector) उपयुक्त एक से मेल खाने के लिए ।

अस्पष्टता को हल करने के लिए आपको उन्हें querystring या मार्ग पैरामीटर द्वारा अलग करना होगा।


14

वेब पर बहुत खोज करने के बाद और यदि निम्न पाया गया हो तो राउटिंग मैप के लिए सबसे उपयुक्त रूप खोजने की कोशिश करना

config.Routes.MapHttpRoute("DefaultApiWithId", "Api/{controller}/{id}", new { id =RouteParameter.Optional }, new { id = @"\d+" });
config.Routes.MapHttpRoute("DefaultApiWithAction", "Api/{controller}/{action}");

ये मैपिंग एक्शन नाम मैपिंग और बुनियादी http कन्वेंशन (GET, POST, PUT, DELETE) दोनों पर लागू होती हैं


9
मेरे लिए यह काम कर गया, लेकिन केवल मार्ग विन्यास में मार्गों के क्रम को बदलने के बाद ताकि कार्रवाई वाला पहला दिखाई दिया
फ्रेड्रिक स्टोलपे 9'15

ठीक यहाँ आदेश महत्वपूर्ण है
AT

5

यह संभव है कि आपके webmethods को उसी url में हल किया जा रहा हो। निम्नलिखित लिंक पर एक नजर: -

http://www.asp.net/web-api/overview/web-api-routing-and-actions/routing-in-aspnet-web-api

इसलिए, आपको अपनी रूटिंग तालिका में अपना मेथडनाम जोड़ने की आवश्यकता हो सकती है।


5

क्रियाओं का उपयोग किए बिना विकल्प होंगे:

  1. विधियों में से एक को किसी भिन्न नियंत्रक पर ले जाएं, ताकि वे टकराएं नहीं।

  2. केवल एक विधि का उपयोग करें जो परम लेता है, और यदि यह आपके कोड से दूसरी विधि को शून्य कहता है।


यह समाधान हो सकता है, लेकिन इष्टतम नहीं है, वैसे भी मेरी तरफ से +1 :)
सतीश कुमार वी

4

इस समाधान ने मेरे लिए काम किया।

कृपया पहले WebApiConfig में रूट 2 रखें। इसके अलावा प्रत्येक विधि से पहले HttpGet और HttpPost जोड़ें और यूआरएल में नियंत्रक का नाम और विधि का नाम शामिल करें।

WebApiConfig =>

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

नियंत्रक =>

public class ValuesController : ApiController
{

    [HttpPost]
    public string GetCustomer([FromBody] RequestModel req)
    {
        return "Customer";
    }

    [HttpPost]
    public string GetCustomerList([FromBody] RequestModel req)
    {
        return "Customer List";
    }
}

उर्ल =>

http://localhost:7050/api/Values/GetCustomer

http://localhost:7050/api/Values/GetCustomerList

4

यह उन सभी के लिए उत्तर है जो सब कुछ जानते हैं और सही है और 50 बार जांच कर चुके हैं .....

सुनिश्चित करें कि आप बार-बार नहीं देख रहे हैं RouteConfig.cs

जिस फाइल को आप एडिट करना चाहते हैं उसका नाम है WebApiConfig.cs

इसके अलावा, यह संभवतः इस तरह दिखना चाहिए:

using System.Web.Http;

namespace My.Epic.Website
{
    public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
          config.MapHttpAttributeRoutes();

          // api/Country/WithStates
          config.Routes.MapHttpRoute(
            name: "ControllerAndActionOnly",
            routeTemplate: "api/{controller}/{action}",
            defaults: new { },
            constraints: new { action = @"^[a-zA-Z]+([\s][a-zA-Z]+)*$" });

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

मैं खुद को लगभग 3 घंटे बचा सकता था।


1
धन्यवाद, आपने मुझे 3 घंटे के लिए बचाया
गिडूब

3

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

पहले मिलता है:

public IEnumerable<SearchItem> Get()
{
...
}

दूसरा मिलता है:

public IEnumerable<SearchItem> Get(int id, [FromUri] List<string> layers)
{
...
}

WebApiConfig:

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

3

यह वेब एपीआई नियंत्रक के बजाय एमवीसी नियंत्रक का उपयोग करने के कारण संभव है। वेब एपीआई नियंत्रक में नाम स्थान की जाँच करें यह निम्नानुसार होना चाहिए

using System.Net;
using System.Net.Http;
using System.Web.Http;

अगर नाम स्थान निम्नलिखित हैं तो यह वेब एपीआई नियंत्रक विधि कॉलिंग में उपरोक्त त्रुटि है

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

2

कृपया जाँचें कि आपके पास दो तरीके हैं जिनमें अलग-अलग नाम और समान पैरामीटर हैं।

यदि हां, तो कृपया किसी भी विधि को हटा दें और प्रयास करें।


2

मैंने अपने वेबएपीआई नियंत्रकों को अतिरिक्त कार्यों के साथ बढ़ाने की कोशिश करते हुए इस समस्या पर ठोकर खाई है।

आप मान लेंगे

public IEnumerable<string> Get()
{
    return this.Repository.GetAll();
}

[HttpGet]
public void ReSeed()
{
    // Your custom action here
}

अब दो विधियाँ हैं जो / api / नियंत्रक के अनुरोध को संतुष्ट करती हैं जो TS द्वारा वर्णित समस्या को ट्रिगर करता है।

मैं अपने अतिरिक्त कार्यों में "डमी" मापदंडों को जोड़ना नहीं चाहता था, इसलिए मैंने डिफ़ॉल्ट कार्यों को देखा और इसके साथ आया:

[ActionName("builtin")]
public IEnumerable<string> Get()
{
    return this.Repository.GetAll();
}

"दोहरी" मार्ग बंधन के साथ संयोजन में पहली विधि के लिए:

config.Routes.MapHttpRoute(
    name: "DefaultApi",
    routeTemplate: "api/{controller}/{id}",
    defaults: new { action = "builtin", id = RouteParameter.Optional },
    constraints: new { id = @"\d+" });

config.Routes.MapHttpRoute(
    name: "CustomActionApi",
    routeTemplate: "api/{controller}/{action}");

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


2

मेरे मामले में सब कुछ सही था

1) वेब कॉन्फ़िगरेशन ठीक से कॉन्फ़िगर किया गया था 2) रूट उपसर्ग और रूट विशेषताएँ उचित थीं

फिर भी मुझे त्रुटि मिल रही थी। मेरे मामले में "रूट" विशेषता (F12 दबाकर) System.Web.MVc को इंगित करता था, लेकिन System.Web.Http को नहीं, जो समस्या का कारण बना।


इस जवाब ने मुझे बहुत मदद की!
tvb108108

1

आप [Route("api/[controller]/[action]")]अपने नियंत्रक वर्ग में जोड़ सकते हैं ।

[Route("api/[controller]/[action]")]
[ApiController]
public class MySuperController : ControllerBase
{
 ...
}

0

मुझे पता है कि यह एक पुराना सवाल है, लेकिन कभी-कभी, जब आप वेबपीआई से जुड़ने के लिए AngularJS जैसे सेवा संसाधनों का उपयोग करते हैं, तो सुनिश्चित करें कि आप सही मार्ग का उपयोग कर रहे हैं, अन्य बुद्धिमान यह त्रुटि होती है।


0

सुनिश्चित करें कि आप डिफ़ॉल्ट GET | PUT | POST | DELETE क्रियाओं के लिए अपने HttpPost / Put / Get / Delete] विशेषता के साथ अपने नियंत्रक तरीकों को न सजाएँ। मैंने अपने वेनिला पोस्ट कंट्रोलर एक्शन में इस अटैब्यूट को जोड़ा था और यह 404 का कारण बना।

आशा है कि यह किसी की मदद करता है क्योंकि यह बहुत निराशाजनक हो सकता है और प्रगति को रोक सकता है।


0

उदाहरण के लिए => टेस्टकंट्रोलर

        [HttpGet]
        public string TestMethod(int arg0)
        {
            return "";
        }

        [HttpGet]
        public string TestMethod2(string arg0)
        {
            return "";
        }

        [HttpGet]
        public string TestMethod3(int arg0,string arg1)
        {
            return "";
        }

यदि आप केवल WebApiConfig.cs फ़ाइल बदल सकते हैं।

 config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{action}/",
                defaults: null
            );

बस :)

और परिणाम: यहां छवि विवरण दर्ज करें


0

क्या आपने कोशिश की जैसे:

[HttpGet("Summary")]
public HttpResponseMessage Summary(MyVm vm)
{
    return null;
}

[HttpGet("FullDetails")]
public HttpResponseMessage FullDetails()
{
    return null;
}

1
यह गैर- .NET कोर प्रोजेक्ट्स में संकलित नहीं होगा, क्योंकि HttpGetविशेषता में एक कंस्ट्रक्टर नहीं है जो एक स्ट्रिंग तर्क को स्वीकार करता है।
होप्पुप्पुनेट
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.