वेब एपीआई पुट रिक्वेस्ट एक Http 405 मेथड इज नॉट अलाउड एरर


134

यहाँ PUTमेरे वेब एपीआई पर विधि के लिए कॉल है - विधि में तीसरी लाइन (मैं ASP.NET MVC बैक से वेब एपीआई कॉल कर रहा हूं):

यहाँ छवि विवरण दर्ज करें

client.BaseAddressहै http://localhost/CallCOPAPI/

यहाँ है contactUri:

यहाँ छवि विवरण दर्ज करें

यहाँ है contactUri.PathAndQuery:

यहाँ छवि विवरण दर्ज करें

और अंत में, यहाँ मेरी 405 प्रतिक्रिया है:

यहाँ छवि विवरण दर्ज करें

यहाँ मेरे Web API प्रोजेक्ट में WebApi.config है:

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

            config.Routes.MapHttpRoute(
                name: "DefaultApiGet",
                routeTemplate: "api/{controller}/{action}/{regionId}",
                defaults: new { action = "Get" },
                constraints: new { httpMethod = new HttpMethodConstraint("GET") });

            var json = config.Formatters.JsonFormatter;
            json.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.Objects;
            config.Formatters.Remove(config.Formatters.XmlFormatter);

मैं रास्ते में पारित हो जाता है कि नीचे अलग करना की कोशिश की किया है PutAsJsonAsyncकरने के लिए string.Format("/api/department/{0}", department.Id)और string.Format("http://localhost/CallCOPAPI/api/department/{0}", department.Id)कोई भाग्य के साथ।

क्या किसी को कोई विचार है कि मुझे 405 त्रुटि क्यों हो रही है?

अपडेट करें

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

फ्रंट एंड डिपार्टमेंट कंट्रोलर

namespace CallCOP.Controllers
{
    public class DepartmentController : Controller
    {
        HttpClient client = new HttpClient();
        HttpResponseMessage response = new HttpResponseMessage();
        Uri contactUri = null;

        public DepartmentController()
        {
            // set base address of WebAPI depending on your current environment
            client.BaseAddress = new Uri(ConfigurationManager.AppSettings[string.Format("APIEnvBaseAddress-{0}", CallCOP.Helpers.ConfigHelper.COPApplEnv)]);

            // Add an Accept header for JSON format.
            client.DefaultRequestHeaders.Accept.Add(
                new MediaTypeWithQualityHeaderValue("application/json"));
        }

        // need to only get departments that correspond to a Contact ID.
        // GET: /Department/?regionId={0}
        public ActionResult Index(int regionId)
        {
            response = client.GetAsync(string.Format("api/department/GetDeptsByRegionId/{0}", regionId)).Result;
            if (response.IsSuccessStatusCode)
            {
                var departments = response.Content.ReadAsAsync<IEnumerable<Department>>().Result;
                return View(departments);
            }
            else
            {
                LoggerHelper.GetLogger().InsertError(new Exception(string.Format(
                    "Cannot retrieve the list of department records due to HTTP Response Status Code not being successful: {0}", response.StatusCode)));
                return RedirectToAction("Index");
            }

        }

        //
        // GET: /Department/Create

        public ActionResult Create(int regionId)
        {
            return View();
        }

        //
        // POST: /Department/Create
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Create(int regionId, Department department)
        {
            department.RegionId = regionId;
            response = client.PostAsJsonAsync("api/department", department).Result;
            if (response.IsSuccessStatusCode)
            {
                return RedirectToAction("Edit", "Region", new { id = regionId });
            }
            else
            {
                LoggerHelper.GetLogger().InsertError(new Exception(string.Format(
                    "Cannot create a new department due to HTTP Response Status Code not being successful: {0}", response.StatusCode)));
                return RedirectToAction("Edit", "Region", new { id = regionId });
            }
        }

        //
        // GET: /Department/Edit/5

        public ActionResult Edit(int id = 0)
        {
            response = client.GetAsync(string.Format("api/department/{0}", id)).Result;
            Department department = response.Content.ReadAsAsync<Department>().Result;
            if (department == null)
            {
                return HttpNotFound();
            }
            return View(department);
        }

        //
        // POST: /Department/Edit/5

        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Edit(int regionId, Department department)
        {
            response = client.GetAsync(string.Format("api/department/{0}", department.Id)).Result;
            contactUri = response.RequestMessage.RequestUri;
            response = client.PutAsJsonAsync(string.Format(contactUri.PathAndQuery), department).Result;
            if (response.IsSuccessStatusCode)
            {
                return RedirectToAction("Index", new { regionId = regionId });
            }
            else
            {
                LoggerHelper.GetLogger().InsertError(new Exception(string.Format(
                    "Cannot edit the department record due to HTTP Response Status Code not being successful: {0}", response.StatusCode)));
                return RedirectToAction("Index", new { regionId = regionId });
            }
        }

        //
        // GET: /Department/Delete/5

        public ActionResult Delete(int id = 0)
        {
            response = client.GetAsync(string.Format("api/department/{0}", id)).Result;
            Department department = response.Content.ReadAsAsync<Department>().Result;

            if (department == null)
            {
                return HttpNotFound();
            }
            return View(department);
        }

        //
        // POST: /Department/Delete/5

        [HttpPost, ActionName("Delete")]
        [ValidateAntiForgeryToken]
        public ActionResult DeleteConfirmed(int regionId, int id)
        {
            response = client.GetAsync(string.Format("api/department/{0}", id)).Result;
            contactUri = response.RequestMessage.RequestUri;
            response = client.DeleteAsync(contactUri).Result;
            return RedirectToAction("Index", new { regionId = regionId });
        }
    }
}

वेब एपीआई विभाग ApiController

namespace CallCOPAPI.Controllers
{
    public class DepartmentController : ApiController
    {
        private CallCOPEntities db = new CallCOPEntities(HelperClasses.DBHelper.GetConnectionString());

        // GET api/department
        public IEnumerable<Department> Get()
        {
            return db.Departments.AsEnumerable();
        }

        // GET api/department/5
        public Department Get(int id)
        {
            Department dept = db.Departments.Find(id);
            if (dept == null)
            {
                throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotFound));
            }

            return dept;
        }

        // this should accept a contact id and return departments related to the particular contact record
        // GET api/department/5
        public IEnumerable<Department> GetDeptsByRegionId(int regionId)
        {
            IEnumerable<Department> depts = (from i in db.Departments
                                             where i.RegionId == regionId 
                                             select i);
            return depts;
        }

        // POST api/department
        public HttpResponseMessage Post(Department department)
        {
            if (ModelState.IsValid)
            {
                db.Departments.Add(department);
                db.SaveChanges();

                HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.Created, department);
                return response;
            }
            else
            {
                return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState);
            }
        }

        // PUT api/department/5
        public HttpResponseMessage Put(int id, Department department)
        {
            if (!ModelState.IsValid)
            {
                return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState);
            }

            if (id != department.Id)
            {
                return Request.CreateResponse(HttpStatusCode.BadRequest);
            }

            db.Entry(department).State = EntityState.Modified;

            try
            {
                db.SaveChanges();
            }
            catch (DbUpdateConcurrencyException ex)
            {
                return Request.CreateErrorResponse(HttpStatusCode.NotFound, ex);
            }

            return Request.CreateResponse(HttpStatusCode.OK);
        }

        // DELETE api/department/5
        public HttpResponseMessage Delete(int id)
        {
            Department department = db.Departments.Find(id);
            if (department == null)
            {
                return Request.CreateResponse(HttpStatusCode.NotFound);
            }

            db.Departments.Remove(department);

            try
            {
                db.SaveChanges();
            }
            catch (DbUpdateConcurrencyException ex)
            {
                return Request.CreateErrorResponse(HttpStatusCode.NotFound, ex);
            }

            return Request.CreateResponse(HttpStatusCode.OK, department);
        }
    }
}

क्या आपको [HttpPut]एक्शन विधि की परिभाषा से पहले उपयोग नहीं करना चाहिए ? ( [HttpPost]और [HttpDelete]जहाँ उपयुक्त हो)
क्रिस प्रैट

@ChrisPratt बस स्पष्ट होने के लिए, आपका मतलब है [HttpPut]WebAPI नियंत्रक (ApiController), सही है? क्योंकि डिपार्टमेंट के लिए फ्रंट एंड कंट्रोलर (एडिट मेथड) की एक [HttpPost]विशेषता है।
माइक मार्क्स

1
@ChrisPratt वैल्यूसेंटरोल्टर (जो कि वेबएपीआई टेम्पलेट के साथ आता है) [HttpPut]में पुट / पोस्ट / डिलीट मेथड्स आदि के गुण नहीं हैं
माइक मार्क्स

हां, मुझे यकीन है कि इसे वेब एपीआई की ओर से जरूरत है। व्यक्तिगत रूप से, मैंने हमेशा वेब एपीआई सामान के लिए केवल एट्रीब्यूटिंग का उपयोग किया है, इसलिए मेरा स्मरण थोड़ा स्केच है।
क्रिस प्रैट

जाहिरा तौर पर यह WebDAV की बात थी .. मैंने यह सुनिश्चित करने के लिए अपने स्थानीय IIS (Windows सुविधाएँ) की जाँच की और यह नहीं कहा कि यह नहीं था ... वैसे भी मैंने इस पर एक उत्तर पोस्ट किया है, मूल रूप से अपने वेब के अंदर मॉड्यूल WebDAV को हटा रहा है। .config।
माइक मार्क्स

जवाबों:


304

इसलिए, मैंने यह सुनिश्चित करने के लिए विंडोज फीचर्स की जाँच की कि मेरे पास यह चीज़ नहीं है जिसे WebDAV इंस्टॉल किया गया है, और यह कहा कि मैंने नहीं किया। वैसे भी, मैं आगे गया और अपने वेब में निम्नलिखित रखा। मैंने इसे अंदर रखा <system.webServer>

<modules runAllManagedModulesForAllRequests="true">
    <remove name="WebDAVModule"/> <!-- add this -->
</modules>

इसके अतिरिक्त, अक्सर web.configहैंडलर में निम्नलिखित जोड़ना आवश्यक होता है । बाबाक धन्यवाद

<handlers>
    <remove name="WebDAV" />
    ...
</handlers>

2
हाहा ... हाँ ... मैं हार मानने वाला था। तो हाँ। WebDAV आपके में सक्षम होना चाहिए applicationhost.config। खुशी है कि आपने इसे ठीक कर लिया है।
एरॉन

9
आपको इसे जोड़ना भी पड़ सकता है,:<handlers><remove name="WebDAV" />...
बाबाक

14
इसे केवल मेरे WebApi web.config में जोड़ा गया और इसने काम किया।
Fordy

भले ही IE10 में इस कॉन्फिग के बिना भी यह ठीक काम कर रहा था, मुझे इसे क्रोम ब्राउज़र में काम करने के लिए केवल WebApi web.config में ही करना था।
डेनिस आर

1
वास्तव में कष्टप्रद समस्या के उत्तर के लिए धन्यवाद। यह पहली जगह में क्यों होता है?
स्कॉट विल्सन

23

WebDav-SchmebDav .. .. सुनिश्चित करें कि आपने आईडी के साथ यूआरएल सही तरीके से बनाया है। इसे http://www.fluff.com/api/Fluff?id=MyID की तरह न भेजें , इसे http://www.fluff.com/api/Fluff/MyID की तरह भेजें ।

उदाहरण के लिए।

PUT http://www.fluff.com/api/Fluff/123 HTTP/1.1
Host: www.fluff.com
Content-Length: 11

{"Data":"1"}

यह एक छोटे से अनंत काल के लिए मेरी गेंदों को तोड़ रहा था, कुल शर्मिंदगी।


3
मेरे लिए एक अतिरिक्त बॉल बस्टर: PUT क्रियाएँ आदिम प्रकार के मापदंडों के डेटा को बाँध नहीं सकती हैं। मैं बदलना पड़ा public int PutFluffColor(int Id, int colorCode)करने के लिएpublic int PutFluffColor(int Id, UpdateFluffColorModel model)
जोश नोए

4
काश मैं इसे WebDav-SchmebDav के लिए दो बार बढ़ा सकता
नोएल

1
समाधान तक पहुंचने के 8 घंटे से अधिक काम करने के बाद, हर कोई वेब की सिफारिश कर रहा है। कॉनफिग ने अपने इतने अद्भुत बदलाव को बदल दिया है कि कोई भी शरीर इस संभावना के बारे में बात नहीं करता है।
सायरन

22

इसे अपने में जोड़ें web.config। आपको IIS को बताने की जरूरत है कि क्या PUT PATCH DELETEऔर क्या OPTIONSमतलब है। और कौन सा IHttpHandlerआह्वान करना है।

<configuation>
    <system.webServer>
    <handlers>
    <remove name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" />
    <remove name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" />
    <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
    <add name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
    <add name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
    <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
    </handlers>
    </system.webServer>
</configuration>

यह भी जांचें कि आपके पास WebDAV सक्षम नहीं है।


मेरे पास पहले से ही है। मैं यह मान रहा हूं कि इसे वेब एपीआई प्रोजेक्ट में डाला जाना चाहिए, न कि मेरे फ्रंट एंड एमवीसी प्रोजेक्ट में, सही?
माइक मार्क्स

मेरे पास WebDAV स्थापित नहीं है। इसके अतिरिक्त, क्या आप कह रहे हैं कि ऊपर web.config कोड को web.config परियोजना में रखा जाना चाहिए जो वेब API को कॉल करता है?
माइक मार्क्स

यह वास्तव में दोनों web.configs में है ... :(
माइक मार्क्स

अरे नहीं ... मुझे लगा कि आप एमवीसी प्रोजेक्ट से वेब एपीआई प्रोजेक्ट का संदर्भ ले रहे हैं।
एरोन

1
क्या आप विभाग सूची के कोड सूची को पोस्ट कर सकते हैं? यह सब। समस्या आपके वेब एपीआई प्रोजेक्ट में निहित है, और यह नहीं जानता कि कैसे संभालना है PUT, यही 405 का मतलब है। जाँच करें कि GET काम करता है, बस रूटिंग को नियमबद्ध करने के लिए। पुनश्च। स्क्रीनशॉट के बजाय पेस्ट कोड कॉपी करने की कोशिश करें। PPS, का उपयोग न करें Task.Result, आप कुछ स्थितियों में असंबंधित थ्रेडिंग मुद्दे प्राप्त करेंगे। इसके बजाय पूरी विधि को async प्रतीक्षा में बदल दें। इसका उल्लेख नहीं करने के लिए यह तुल्यकालिक, बहुपरत अवरुद्ध कोड बनाता है (एकल थ्रेड की तुलना में धीमा)।
एरोन

14

मैं IIS 8.5 पर ASP.NET MVC 5 एप्लिकेशन चला रहा हूं। मैंने यहाँ पोस्ट की गई सभी विविधताओं को आज़माया, और यह मेरी web.configतरह दिखती है:

<system.webServer>
    <modules runAllManagedModulesForAllRequests="true">
        <remove name="WebDAVModule"/> <!-- add this -->
    </modules>  
    <handlers>      
      <remove name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" />
      <remove name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" />
      <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
      <remove name="WebDAV" />
      <add name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
      <add name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
      <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
    </handlers> 
</system.webServer>

मैं अपने सर्वर से WebDav की स्थापना रद्द नहीं कर सका क्योंकि मेरे पास व्यवस्थापक विशेषाधिकार नहीं थे। इसके अलावा, कभी-कभी मुझे method not allowed.css और .js फाइलें मिल रही थीं । अंत में, ऊपर दिए गए कॉन्फ़िगरेशन के साथ सब कुछ फिर से काम करना शुरू कर दिया।


5

[FromBody] के साथ एक्शन पारमों में से एक को सजाने से मेरे लिए समस्या हल हो गई:

public async Task<IHttpActionResult> SetAmountOnEntry(string id, [FromBody]int amount)

हालाँकि ASP.NET इसे सही ढंग से परिभाषित करेगा यदि विधि पैरामीटर का उपयोग विधि पैरामीटर में किया गया था:

public async Task<IHttpActionResult> UpdateEntry(string id, MyEntry entry)

1

इसका एक और कारण हो सकता है यदि आप "आईडी" के लिए डिफ़ॉल्ट चर नाम का उपयोग नहीं करते हैं जो वास्तव में है: आईडी।


0

मेरे मामले में त्रुटि 405 को स्थैतिक हैंडलर द्वारा मार्ग ("एपीआई / चित्र") के कारण उसी नाम के फ़ोल्डर ("~ / चित्र") के साथ परस्पर विरोधी द्वारा लागू किया गया था।


0

आप विशेष रूप से IIS में GUI से मैन्युअल रूप से webdav मॉड्यूल निकाल सकते हैं।
1) गोटो II।
2) संबंधित साइट पर जाएं।
3) "हैंडलर मैपिंग" खोलें
। नीचे स्क्रॉल करें और WebDav मॉड्यूल चुनें। इस पर राइट क्लिक करें और इसे हटा दें।

नोट: यह आपके web.config के वेब ऐप को भी अपडेट करेगा।


-1

आपका क्लाइंट एप्लिकेशन और सर्वर एप्लिकेशन एक ही डोमेन के अंतर्गत होना चाहिए, उदाहरण के लिए:

ग्राहक - लोकलहोस्ट

सर्वर - लोकलहोस्ट

और नहीं :

ग्राहक - लोकलहोस्ट: २१२३४

सर्वर - लोकलहोस्ट


2
मुझे ऐसा नहीं लगता। एक सेवा बनाने का उद्देश्य एक अन्य डोमेन
ओज़ान BAYRAM

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

CORS 405 "Method Not Allowed" देगा, उदाहरण के लिए: URL का अनुरोध करें: testapi.nottherealsite.com/api/Reporting/RunReport अनुरोध विधि: विकल्प स्थिति कोड: 405 विधि अनुमति नहीं है कि कृपया यहां stackoverflow.com/questions/12458444/…
लेव के।

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