幸運的是,我能夠找到解決自己。讓我告訴你我是如何運作起來的。
- 定製控制部和動作選擇器被轉發所請求的語言和當前的HTTP響應代碼:
public class CustomDefaultHttpControllerSelector: DefaultHttpControllerSelector
{
public CustomDefaultHttpControllerSelector(HttpConfiguration configuration) : base(configuration)
{
}
public override HttpControllerDescriptor SelectController(HttpRequestMessage request)
{
HttpControllerDescriptor descriptor = null;
try
{
descriptor = base.SelectController(request);
}
catch (HttpResponseException e)
{
var routeValues = request.GetRouteData().Values;
routeValues.Clear();
routeValues["controller"] = "Error";
routeValues["action"] = "Main";
routeValues["code"] = e.Response.StatusCode;
routeValues["language"] = request.Headers?.AcceptLanguage?.FirstOrDefault()?.Value ?? "en";
descriptor = base.SelectController(request);
}
return descriptor;
}
}
public class CustomControllerActionSelector: ApiControllerActionSelector
{
public CustomControllerActionSelector()
{
}
public override HttpActionDescriptor SelectAction(HttpControllerContext controllerContext)
{
HttpActionDescriptor descriptor = null;
try
{
descriptor = base.SelectAction(controllerContext);
}
catch (HttpResponseException e)
{
var routeData = controllerContext.RouteData;
routeData.Values.Clear();
routeData.Values["action"] = "Main";
routeData.Values["code"] = e.Response.StatusCode;
routeData.Values["language"] = controllerContext.Request?.Headers?.AcceptLanguage?.FirstOrDefault()?.Value ?? "en";
IHttpController httpController = new ErrorController();
controllerContext.Controller = httpController;
controllerContext.ControllerDescriptor = new HttpControllerDescriptor(controllerContext.Configuration, "Error", httpController.GetType());
descriptor = base.SelectAction(controllerContext);
}
return descriptor;
}
}
兩個重要的變化:
1.1。路由值列表需要清除。否則,它會嘗試在ErrorController
中查找映射到此值列表的操作。
1.2。增加了code
和language
。
- 的
ErrorController
本身:
[RoutePrefix("error")]
public class ErrorController: BaseController
{
[HttpGet, HttpPost, HttpPut, HttpDelete, HttpHead, HttpOptions, AcceptVerbs("PATCH")]
[Route("{code}/{language}")]
public HttpResponseMessage Main(string code, string language)
{
HttpStatusCode parsedCode;
var responseMessage = new HttpResponseMessage();
if (!Enum.TryParse(code, true, out parsedCode))
{
parsedCode = HttpStatusCode.InternalServerError;
}
responseMessage.StatusCode = parsedCode;
...
}
}
我已經去除了路由映射routes.MapHttpRoute(...)
。無論我在瀏覽器中輸入什麼,它都不會調用Handle404
。
HTTP狀態400(壞請求)未被覆蓋。按照http://www.asp.net/web-api/overview/formats-and-model-binding/model-validation-in-aspnet-web-api(「處理驗證錯誤」部分)中的說明使用ValidationModelAttribute
可以輕鬆實現此目的。
也許這將幫助別人......
1.1點幫助別人。 :) – teedyay