GoogleとStackOverflowでASP.NETWeb APIで許可されていない405メソッドのすべての回答を確認しましたが、どのソリューションも機能していません。
ASP.NET Web APIを作成していて、2つのダミーコントローラーがあります。
一方のコントローラーにはHTTPDeleteメソッドを使用できますが、もう一方のコントローラーには使用できません。
バリューコントローラー
using System.Collections.Generic;
using System.Web.Http;
namespace JobSite_WebAPI.Controllers
{
public class ValuesController : ApiController
{
List<string> strings = new List<string>()
{
"value1", "value2","value3"
};
// GET api/values
public IEnumerable<string> Get()
{
return strings;
}
// GET api/values/5
public string Get(int id)
{
return strings[id];
}
// DELETE api/values/5
public void Delete(int id)
{
strings.RemoveAt(id);
}
}
}
ジョブ詳細コントローラー
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using DataAccess;
namespace JobSite_WebAPI.Controllers
{
public class JobDetailController : ApiController
{
public JobDetailController()
{
JobSiteEntities entities = new JobSiteEntities();
entities.Configuration.ProxyCreationEnabled = false;
}
public IEnumerable<JobDetail>Get()
{
using (JobSiteEntities entities = new JobSiteEntities())
{
return entities.JobDetails.ToList();
}
}
[HttpGet]
public HttpResponseMessage Get(int id)
{
using (JobSiteEntities entities = new JobSiteEntities())
{
var entity = entities.JobDetails.FirstOrDefault(e => e.JOBID == id);
if (entity != null)
{
return Request.CreateResponse(HttpStatusCode.OK, entity);
}
else
{
return Request.CreateErrorResponse(HttpStatusCode.NotFound, "Job With Id = " + id.ToString() + " not found");
}
}
}
[HttpGet]
public HttpResponseMessage RetrieveJobByLocation(string locationName)
{
try
{
using (JobSiteEntities entities = new JobSiteEntities())
{
IEnumerable<JobDetail> jobDetails = entities.JobDetails.Where(e => e.Location.LocationName.ToLower() == locationName).ToList();
if (jobDetails != null)
return Request.CreateResponse(HttpStatusCode.OK, jobDetails);
else
return Request.CreateResponse(HttpStatusCode.NotFound);
}
}
catch(Exception ex)
{
return Request.CreateResponse(HttpStatusCode.BadRequest, ex);
}
}
[HttpDelete]
public HttpResponseMessage Delete(int jobId)
{
try
{
using (JobSiteEntities entities = new JobSiteEntities())
{
var entity = entities.JobDetails.FirstOrDefault(e => e.JOBID == jobId);
if (entity == null)
{
return Request.CreateResponse(HttpStatusCode.NotFound, "Job Id with id " + jobId + "is not found");
}
else
{
entities.JobDetails.Remove(entity);
entities.SaveChanges();
return Request.CreateResponse(HttpStatusCode.OK);
}
}
}
catch (Exception ex)
{
return Request.CreateResponse(HttpStatusCode.BadRequest, ex);
}
}
}
}
WebAPIConfig.cs
var cors = new EnableCorsAttribute("*", "*", "*");
config.EnableCors(cors);
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/octet-stream"));
Web.Config
<remove name="WebDAV" />
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<remove name="OPTIONSVerbHandler" />
<remove name="TRACEVerbHandler" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
CORSを有効にし、WebDAVを無効にしました。また、削除メソッドにHTTPDelete属性を追加しました。
直面している問題は、Value ControllerのDeleteメソッドがFiddlerから正常に機能することですが、JobDetailsControllerの場合は許可されていない405メソッドを取得します。
GETとPOST Method.AmもPUTで同じ問題に直面しています。
fiddlerからのエラーメッセージのスクリーンショットを追加しました。Fiddler URLFiddlerエラーメッセージ
コンベンションベースのルートテンプレート...のため、ValuesController
で機能します。
_"api/{controller}/{id}"
_
コントローラーが準拠する_{id}
_プレースホルダーがありますが、JobDetailController.Delete(int jobId)
はjobId
パラメーター名のため、ルートテンプレートと一致しません。これらのパラメータ引数を_int id
_に変更して、規則で設定されたルートテンプレートと一致させます。
_[HttpDelete]
public HttpResponseMessage Delete(int id) {
//...
}
_
それ以外の場合は、config.MapHttpAttributeRoutes()
でも有効になっているため、代わりに属性ルーティングを使用できます。
参照: ASP.NET Web API 2の属性ルーティング
_[RoutePrefix("api/JobDetail")]
public class JobDetailController : ApiController {
[HttpGet]
[Route("")] //Matches GET api/jobdetail
public IEnumerable<JobDetail> Get() {
//...
}
[HttpGet]
[Route("{id:int}")] //Matches GET api/jobdetail/1
public HttpResponseMessage Get(int id) {
//...
}
[HttpGet]
[Route("{locationName}")] //Matches GET api/jobdetail/somewhere
public HttpResponseMessage RetrieveJobByLocation(string locationName) {
//...
}
[HttpDelete]
[Route("{jobId:int}")] //Matches DELETE api/jobdetail/1
public HttpResponseMessage Delete(int jobId) {
//...
}
}
_
コントローラにルーティングする場合は、慣例または属性のいずれかであり、両方ではないことに注意してください。属性によってアクションにルーティングする場合、コントローラー上の他のすべてのアクションにも属性ルーティングが必要です。