Voici l'appel à la PUT
méthode sur mon API Web - la troisième ligne de la méthode ( j'appelle l' API Web à partir d'un frontal ASP.NET MVC):
client.BaseAddress
est http://localhost/CallCOPAPI/
.
Voici contactUri
:
Voici contactUri.PathAndQuery
:
Et enfin, voici ma réponse 405:
Voici le WebApi.config dans mon projet d'API Web:
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);
J'ai essayé de décapage sur le chemin qui est passé dans PutAsJsonAsync
à string.Format("/api/department/{0}", department.Id)
et string.Format("http://localhost/CallCOPAPI/api/department/{0}", department.Id)
sans chance.
Quelqu'un a-t-il une idée de la raison pour laquelle j'obtiens l'erreur 405?
METTRE À JOUR
Selon la demande, voici mon code de contrôleur de département (je publierai à la fois le code de contrôleur de département pour mon projet frontal, ainsi que le code ApiController de département pour WebAPI):
Contrôleur de département frontal
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 });
}
}
}
Service API Web 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);
}
}
}
la source
[HttpPut]
avant la définition de la méthode d'action? ([HttpPost]
et le[HttpDelete]
cas échéant également)[HttpPut]
sur le contrôleur WebAPI (ApiController), non? Parce que le contrôleur frontal pour Department (méthode Edit) a un[HttpPost]
attribut.[HttpPut]
, etc. d'attributs sur les méthodes Put / Post / Delete ..Réponses:
Donc, j'ai vérifié les fonctionnalités de Windows pour m'assurer que je n'avais pas installé cette chose appelée WebDAV, et cela a dit que je ne l'avais pas. Quoi qu'il en soit, je suis allé de l'avant et j'ai placé ce qui suit dans mon web.config (à la fois frontal et WebAPI, juste pour être sûr), et cela fonctionne maintenant. J'ai placé ça à l'intérieur
<system.webServer>
.De plus, il est souvent nécessaire d'ajouter les éléments suivants
web.config
dans les gestionnaires. Merci à Babakla source
applicationhost.config
. Heureux que vous ayez résolu le problème.<handlers><remove name="WebDAV" />...
WebDav-SchmebDav .. .. assurez-vous de créer correctement l'url avec l'ID. Ne l'envoyez pas comme http://www.fluff.com/api/Fluff?id=MyID , envoyez-le comme http://www.fluff.com/api/Fluff/MyID .
Par exemple.
Cela m'a brisé les couilles pendant une petite éternité, un embarras total.
la source
public int PutFluffColor(int Id, int colorCode)
pourpublic int PutFluffColor(int Id, UpdateFluffColorModel model)
Ajoutez ceci à votre
web.config
. Vous devez dire à IIS cePUT
PATCH
DELETE
queOPTIONS
signifie et ce que cela signifie. Et quiIHttpHandler
invoquer.Vérifiez également que WebDAV n'est pas activé.
la source
PUT
, c'est ce que veut dire 405. Vérifiez que GET fonctionne, juste pour exclure le routage. PS. Essayez de copier le code collé plutôt que la capture d'écran. PPS, NE PAS UTILISERTask.Result
, vous aurez des problèmes de filetage sans rapport dans certaines situations. Transformez simplement toute la méthode en attente asynchrone. Sans oublier qu'il crée du code bloqué synchrone et multithread (plus lent qu'un thread unique).J'exécute une application ASP.NET MVC 5 sur IIS 8.5. J'ai essayé toutes les variantes publiées ici, et voici à quoi je
web.config
ressemble:Je n'ai pas pu désinstaller WebDav de mon serveur car je n'avais pas de privilèges d'administrateur. Aussi, parfois, j'obtenais les
method not allowed
fichiers .css et .js. En fin de compte, avec la configuration ci-dessus, tout a recommencé à fonctionner.la source
La décoration de l'un des paramètres d'action avec [FromBody] a résolu le problème pour moi:
Cependant, ASP.NET l'inférerait correctement si un objet complexe était utilisé dans le paramètre de méthode:
la source
Une autre cause de ceci pourrait être si vous n'utilisez pas le nom de variable par défaut pour "id" qui est en fait: id.
la source
Dans mon cas, l'erreur 405 a été invoquée par le gestionnaire statique en raison d'une route ("api / images") en conflit avec le dossier du même nom ("~ / images").
la source
Vous pouvez supprimer manuellement le module webdav de l'interface graphique pour le particulier dans IIS.
1) Aller aux II.
2) Accédez au site respectif.
3) Ouvrez "Handler Mappings".
4) Faites défiler vers le bas et sélectionnez le module WebDav. Faites un clic droit dessus et supprimez-le.
Remarque: cela mettra également à jour votre web.config de l'application Web.
la source
Votre application cliente et votre application serveur doivent être sous le même domaine, par exemple:
client - localhost
serveur - localhost
et pas :
client - localhost: 21234
serveur - localhost
la source