Inilah panggilan ke PUT
metode pada API Web saya - baris ketiga dalam metode (Saya memanggil API Web dari ujung depan ASP.NET MVC):
client.BaseAddress
adalah http://localhost/CallCOPAPI/
.
Inilah contactUri
:
Inilah contactUri.PathAndQuery
:
Dan akhirnya, inilah tanggapan 405 saya:
Inilah WebApi.config dalam proyek API Web saya:
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);
Saya sudah mencoba melucuti menuruni jalan yang akan masuk ke PutAsJsonAsync
ke string.Format("/api/department/{0}", department.Id)
dan string.Format("http://localhost/CallCOPAPI/api/department/{0}", department.Id)
tidak berhasil.
Adakah yang tahu mengapa saya mendapatkan error 405?
MEMPERBARUI
Sesuai permintaan, inilah kode pengontrol Departemen saya (saya akan memposting kode pengontrol Departemen untuk proyek front end saya, serta kode Departemen ApiController untuk WebAPI):
Pengontrol Departemen Front End
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 Departemen API Web
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);
}
}
}
sumber
[HttpPut]
sebelum definisi metode tindakan? ([HttpPost]
dan[HttpDelete]
jika perlu juga)[HttpPut]
pengontrol WebAPI (ApiController), kan? Karena pengontrol ujung depan untuk Departemen (metode Edit) memiliki[HttpPost]
atribut.[HttpPut]
, dll. Atribut pada metode Put / Post / Delete ..Jawaban:
Jadi, saya memeriksa Fitur Windows untuk memastikan saya tidak memiliki hal yang disebut WebDAV diinstal, dan katanya saya tidak. Bagaimanapun, saya pergi ke depan dan menempatkan yang berikut di web.config saya (baik front end dan WebAPI, hanya untuk memastikan), dan itu berfungsi sekarang. Saya menempatkan ini di dalam
<system.webServer>
.Selain itu, sering kali diperlukan untuk menambahkan yang berikut ke
web.config
dalam penangan. Terima kasih untuk Babaksumber
applicationhost.config
. Senang Anda sudah memperbaikinya.<handlers><remove name="WebDAV" />...
WebDav-SchmebDav ... ..pastikan Anda membuat url dengan ID dengan benar. Jangan kirim seperti http://www.fluff.com/api/Fluff?id=MyID , kirimkan seperti http://www.fluff.com/api/Fluff/MyID .
Misalnya.
Ini membuatku kesal karena kekekalan kecil, benar-benar memalukan.
sumber
public int PutFluffColor(int Id, int colorCode)
kepublic int PutFluffColor(int Id, UpdateFluffColorModel model)
Tambahkan ini ke
web.config
. Anda perlu memberi tahu IIS apaPUT
PATCH
DELETE
danOPTIONS
artinya. Dan yangIHttpHandler
harus dipanggil.Periksa juga Anda tidak mengaktifkan WebDAV.
sumber
PUT
, itulah yang dimaksud 405. Periksa apakah GET berfungsi, hanya untuk mengesampingkan perutean. PS. Cobalah untuk menyalin kode tempel daripada tangkapan layar. PPS, JANGAN GUNAKANTask.Result
, Anda akan mendapatkan masalah threading yang tidak terkait dalam situasi tertentu. Alih-alih, ubah seluruh metode menjadi async. Belum lagi itu menciptakan sinkron, kode diblokir multithreaded (lebih lambat dari satu threaded)Saya menjalankan aplikasi ASP.NET MVC 5 di IIS 8.5. Saya mencoba semua variasi yang diposting di sini, dan inilah yang
web.config
terlihat seperti:Saya tidak dapat menghapus WebDav dari Server saya karena saya tidak memiliki hak admin. Juga, kadang-kadang saya mendapatkan file
method not allowed
.css dan .js. Pada akhirnya, dengan konfigurasi di atas mengatur semuanya mulai berfungsi kembali.sumber
Dekorasi salah satu aksi params dengan [FromBody] memecahkan masalah bagi saya:
Namun ASP.NET akan menyimpulkannya dengan benar jika objek kompleks digunakan dalam parameter metode:
sumber
Penyebab lain dari hal ini adalah jika Anda tidak menggunakan nama variabel default untuk "id" yang sebenarnya: id.
sumber
Dalam kasus saya kesalahan 405 dipanggil oleh pengendali statis karena rute ("api / gambar") yang bertentangan dengan folder dengan nama yang sama ("~ / gambar").
sumber
Anda dapat menghapus modul webdav secara manual dari GUI untuk khususnya di IIS.
1) Pergi ke IIs.
2) Mendapat situs masing-masing.
3) Buka "Pemetaan Handler"
4) Gulir ke bawah dan pilih modul WebDav. Klik kanan padanya dan hapus.
Catatan: ini juga akan memperbarui web.config Anda dari aplikasi web.
sumber
Aplikasi klien dan aplikasi server Anda harus di bawah domain yang sama, misalnya:
client - localhost
server - localhost
dan tidak :
client - localhost: 21234
server - localhost
sumber