【问题标题】:Why do I get an HTTP 404 on this one Web API request?为什么我在这个 Web API 请求上得到 HTTP 404?
【发布时间】:2016-11-26 03:52:40
【问题描述】:

我正在向此控制器和操作发出 POST 请求,并收到 404 - Not Found 错误:

[AllowAnonymous]
[System.Web.Mvc.RoutePrefix("api/Appt")]
public class AppointmentController : BaseController
{
    [HttpPost]
    [Route("")]
    public AppointmentDto Post(AppointmentDto model)
    {
        Db.Appointments.Add(model);
        Db.SaveChanges();
        Logger.Info($"Appointment ID {model.Id} created.");
        return model;
    }
}

该请求是使用来自 Microsoft.AspNet.WebApi.Client 包的 HttpClient 从 WPF 客户端发出的。客户端配置如下:

public abstract class BaseRestClient
{
    protected const string BaseAddress = "http://localhost:51009";
    protected HttpClient Client;

    protected virtual void ConfigureClient()
    {
        Client = new HttpClient { BaseAddress = new Uri(BaseAddress) };
        Client.DefaultRequestHeaders.Clear();
        Client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
    }
}

并调用如下:

var response = await Client.PostAsJsonAsync("api/Appt", model, cancellationToken);

response 上的属性包括:

StatusCode: 404`
ReasonPhrase: 'Not Found'`
RequestMessage: 
    {Method: POST, RequestUri: 'http://localhost:51009/api/Appt'`

这是我对 POST 动作的唯一请求,带有 model 参数,但具有讽刺意味的是,在几乎相同的控制器上对 GET 动作的 POST 请求工作正常。使用控制器:

[System.Web.Mvc.RoutePrefix("api/Person")]
public class PersonController : BaseController
{
    [HttpPost]
    public async Task<IEnumerable<PersonDto>> Get()
    {
        Db.Configuration.LazyLoadingEnabled = false;
        return await Db.Persons.ToListAsync();
    }
}

如下提出的请求可以正常工作并返回我所有的Person 对象:

HttpResponseMessage response = await Client.PostAsync("api/Person", null, cancellationToken);

GET 操作的两个类似请求也可以完美运行。

那么为什么会找到一个资源,而另一个却找不到呢?除了找不到请求的资源之外,还有其他隐藏的原因会返回 404 吗?

这可能是由于与两种类型的路由冲突,例如

config.MapHttpAttributeRoutes();

config.Routes.MapHttpRoute(
    name: "DefaultApi",
    routeTemplate: "api/{controller}/{id}",
    defaults: new { id = RouteParameter.Optional }
);

我必须在一个地方使用属性路由,评论解释了原因:

[HttpPost]
[Route("Get")] 
// NOTE HTTP 405 - Method not allowed when this action is named 'Get'.
public async Task<IEnumerable<BranchDto>> Fetch()
{
    Db.Configuration.LazyLoadingEnabled = false;
    return await Db.Branches.ToListAsync();
}

【问题讨论】:

    标签: c# wpf asp.net-web-api dotnet-httpclient asp.net-web-api-routing


    【解决方案1】:

    您使用了错误的路由前缀属性。

    System.Web.Mvc.RoutePrefix("api/Appt")
    

    适用于 MVC 而不是 Web API。

    你需要System.Web.Http中的那个

    System.Web.Http.RoutePrefix("api/Appt")
    

    人员控制器示例起作用的原因是因为它默认回到基于约定的路由。

    如果您通过基于约定的路由调用POST http://localhost:51009/api/Appointment,则原来的会起作用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多