Hier ist der Aufruf der PUT
Methode in meiner Web-API - die dritte Zeile in der Methode (ich rufe die Web-API von einem ASP.NET MVC-Frontend aus auf):
client.BaseAddress
ist http://localhost/CallCOPAPI/
.
Hier ist contactUri
:
Hier ist contactUri.PathAndQuery
:
Und zum Schluss hier meine 405-Antwort:
Hier ist die WebApi.config in meinem Web-API-Projekt:
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);
Ich habe versucht, den Weg, der PutAsJsonAsync
zu string.Format("/api/department/{0}", department.Id)
und string.Format("http://localhost/CallCOPAPI/api/department/{0}", department.Id)
ohne Glück führt, abzustreifen.
Hat jemand eine Idee, warum ich den 405-Fehler erhalte?
AKTUALISIEREN
Auf Anfrage ist hier mein Abteilungscontroller-Code (ich werde sowohl den Abteilungscontroller-Code für mein Front-End-Projekt als auch den Abteilungs-ApiController-Code für die WebAPI veröffentlichen):
Controller der Front-End-Abteilung
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-Abteilung 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);
}
}
}
quelle
[HttpPut]
vor der Definition der Aktionsmethode verwenden? ([HttpPost]
und[HttpDelete]
gegebenenfalls auch)[HttpPut]
den WebAPI-Controller (ApiController) einzuschalten, oder? Weil der Front-End-Controller für Abteilung (Bearbeitungsmethode) ein[HttpPost]
Attribut hat.[HttpPut]
usw. Attribute für die Put / Post / Delete-Methoden.Antworten:
Also habe ich die Windows-Funktionen überprüft, um sicherzustellen, dass ich dieses Ding namens WebDAV nicht installiert habe, und es heißt, dass ich es nicht getan habe. Wie auch immer, ich habe Folgendes in meine web.config eingefügt (sowohl Front-End als auch WebAPI, nur um sicherzugehen), und es funktioniert jetzt. Ich habe das hineingelegt
<system.webServer>
.Darüber hinaus ist es häufig erforderlich,
web.config
in den Handlern Folgendes hinzuzufügen . Danke an Babakquelle
applicationhost.config
. Ich bin froh, dass du es behoben hast.<handlers><remove name="WebDAV" />...
WebDav-SchmebDav .. ..Stellen Sie sicher, dass Sie die URL mit der ID korrekt erstellen. Senden Sie es nicht wie http://www.fluff.com/api/Fluff?id=MyID , sondern wie http://www.fluff.com/api/Fluff/MyID .
Z.B.
Dies sprengte meine Eier für eine kleine Ewigkeit, völlige Verlegenheit.
quelle
public int PutFluffColor(int Id, int colorCode)
zupublic int PutFluffColor(int Id, UpdateFluffColorModel model)
Fügen Sie dies Ihrem hinzu
web.config
. Sie müssen IIS mitteilen, wasPUT
PATCH
DELETE
und wasOPTIONS
bedeutet. Und welcheIHttpHandler
man aufruft.Überprüfen Sie auch, ob WebDAV nicht aktiviert ist.
quelle
PUT
soll. Das bedeutet 405. Überprüfen Sie, ob GET funktioniert, um das Routing auszuschließen. PS. Versuchen Sie, den Einfügecode anstelle des Screenshots zu kopieren. PPS, NICHT VERWENDENTask.Result
, in bestimmten Situationen treten nicht verwandte Threading-Probleme auf. Verwandeln Sie stattdessen einfach die gesamte Methode in asynchrones Warten. Ganz zu schweigen davon, dass synchroner, blockierter Multithread-Code erstellt wird (langsamer als Single-Threaded).Ich führe eine ASP.NET MVC 5-Anwendung unter IIS 8.5 aus. Ich habe alle hier veröffentlichten Variationen ausprobiert und so sehe ich
web.config
aus:Ich konnte WebDav nicht von meinem Server deinstallieren, da ich keine Administratorrechte hatte. Außerdem bekam ich manchmal die
method not allowed
Dateien on .css und .js. Am Ende funktionierte mit der oben eingerichteten Konfiguration alles wieder.quelle
Das Dekorieren eines der Aktionsparameter mit [FromBody] löste das Problem für mich:
ASP.NET würde jedoch korrekt darauf schließen, wenn ein komplexes Objekt im Methodenparameter verwendet würde:
quelle
Eine andere Ursache hierfür könnte sein, dass Sie nicht den Standardvariablennamen für die "ID" verwenden, die tatsächlich lautet: id.
quelle
In meinem Fall wurde der Fehler 405 vom statischen Handler aufgerufen, weil die Route ("api / images") mit dem gleichnamigen Ordner ("~ / images") in Konflikt stand.
quelle
Sie können das webdav-Modul manuell aus der GUI für das jeweilige IIS entfernen.
1) Gehe zu den IIs.
2) Gehen Sie zur jeweiligen Site.
3) Öffnen Sie "Handler-Zuordnungen"
4) Scrollen Sie nach unten und wählen Sie das WebDav-Modul aus. Klicken Sie mit der rechten Maustaste darauf und löschen Sie es.
Hinweis: Dadurch wird auch Ihre web.config der Web-App aktualisiert.
quelle
Ihre Clientanwendung und Serveranwendung müssen sich unter derselben Domäne befinden, zum Beispiel:
client - localhost
Server - localhost
und nicht :
client - localhost: 21234
Server - localhost
quelle