考虑以下两种POST方案:
POST /localhost/api/
- 插入实体,返回200 POST /localhost/api/1324
- 错误请求,返回400 处理场景2的最佳方法是什么?
我什么都不做,并假设使用我的API的开发人员会理解这是错的?我是否在POST方法中添加代码来处理这个并告诉他们这是一个错误的请求?
我意识到返回一个错误的请求可能是最好的事情,这是我最终实现的,但我觉得可能有更好的方法来实现这个我还没有发现。
我的当前代码如下:
[HttpPost]
public HttpResponseMessage Post(MyEntity entity) {
if(entity.Id != null)
throw new HttpResponseException(HttpStatusCode.BadRequest);
MyEntity saved = repository.Insert(entity);
HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.Created, saved);
response.Headers.Location = new Uri(Request.RequestUri, new Uri(saved.Id.ToString(), UriKind.Relative));
return response;
}
// Prevents any attempt to POST with a Guid in the url
[HttpPost]
public void Post(Guid Id) {
throw new HttpResponseException(HttpStatusCode.BadRequest);
}
谢谢!
答案 0 :(得分:3)
你的行为似乎有效。虽然我对是否会这么做有疑问。
<强>校正强>
我说过
如果您没有实现此附加方法,那么路由 会失败,并且通常会返回404.我会的 很想留下这种行为。
但你是对的:
要使其按上述方式运行,即默认为404,您需要以下路线配置:
config.Routes.MapHttpRoute(
name: "DefaultCollectionApi",
routeTemplate: "api/{controller}",
defaults: new { },
constraints: new { httpMethod = new HttpMethodConstraint(HttpMethod.Post) }
);
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { },
constraints: new { httpMethod = new HttpMethodConstraint(HttpMethod.Get, HttpMethod.Put, HttpMethod.Delete) }
);
稍微改善现有方法
但是,如果您确实觉得需要开始监管动词和路由的组合,那么将此逻辑移动到ActionFilterAttribute中可能是值得的。
如果你在顶部添加这条路线,那么它将是en
假设您按照约定对所有路由使用"id"
,您可以快速组合一个过滤器,在RouteValues
中使用id
键查找值,并引发400异常。
public class ValidVerbAndRouteAttribute : ActionFilterAttribute
{
public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
{
object id;
if (actionExecutedContext.ActionContext.ActionArguments.TryGetValue("id", out id) &&
actionExecutedContext.Request.Method == HttpMethod.Post)
{
throw new HttpResponseException(HttpStatusCode.BadRequest);
}
}
}
答案 1 :(得分:2)
您目前的处理方式似乎是正确的。它是标准输入数据验证,如果此验证在RESTful条款中失败,则400是正确的状态代码。
答案 2 :(得分:1)
你想要这样做的方式是正确的,但如果你愿意,还有另一种选择方式。您可以配置路由并声明应该调用具体操作,而不是指定具有签名的操作,如
[HttpPost]
public HttpResponseMessage PostEntity([FromBody]MyEntity entity) {...}
将使用此操作的任何其他签名进行调用,这将导致异常。
路线:
config.Routes.MapHttpRoute(
name: "ActionApi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional });
对于异常处理,我建议使用一个异常过滤器,它包含一组异常类型的映射及其根据您的喜好进行的HttpStatusCode表示。