Web API Put请求生成一个Http 405方法不允许的错误

这里是对我的Web API的PUT方法的调用 – 方法的第三行(我从ASP.NET MVC前端调用Web API):

在这里输入图像描述

client.BaseAddresshttp://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); 

我尝试剥离传递到PutAsJsonAsyncstring.Format("/api/department/{0}", department.Id)string.Format("http://localhost/CallCOPAPI/api/department/{0}", department.Id)没有运气。

有没有人有任何想法,为什么我得到405错误?

UPDATE

根据请求,这是我的部门控制器代码(我将发布我的前端项目的部门控制器代码,以及WebAPI部门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 }); } } } 

Web API部门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); } } } 

所以,我检查了Windowsfunction,以确保我没有安装这个名为WebDAV的东西,它说我没有。 无论如何,我继续把我的web.config(前端和WebAPI,只是肯定)以下放置,现在它的作品。 我把它放在<system.webServer>里面。

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

此外,通常还需要在处理程序中将以下内容添加到web.config中。 感谢Babak

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

将此添加到您的web.config 。 您需要告诉IIS PUT PATCH DELETEOPTIONS含义。 和哪个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-SchmebDav .. ..确保你创build了正确的ID的url。 不要像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"} 

这是一个小永恒我的球,总是尴尬。

我在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,因为我没有pipe理员权限。 此外,有时我得到的method not allowed在.css和.js文件。 最后,随着上面的configuration设置一切再次开始工作。

用[FromBody]装饰其中的一个动作参数为我解决了这个问题:

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

但是,如果在方法参数中使用了复杂的对象,ASP.NET会正确推断它:

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

这可能是另一个原因,如果你不使用默认variables名称为“ID”,其实是:ID。

您的客户端应用程序和服务器应用程序必须位于相同的域下,例如:

客户端 – 本地主机

服务器 – 本地主机

并不是 :

客户端 – 本地主机:21234

服务器 – 本地主机

在我的情况下,由于route(“api / images”)与相同名称的文件夹(“〜/ images”)冲突,错误405被静态处理程序调用。