从我的MVC3控制器操作中,我想返回HTTP 403,将“状态描述”设置为特定的字符串,并在结果内容中返回该字符串,以便在浏览器中可见。
我可以返回ContentResult
来指定内容,但无法返回状态码(例如403)和状态描述。我可以使用HttpStatusCodeResult
来指定状态码和状态描述,但不能指定结果内容。
我如何创建一个包含所有三个参数的操作结果?
从我的MVC3控制器操作中,我想返回HTTP 403,将“状态描述”设置为特定的字符串,并在结果内容中返回该字符串,以便在浏览器中可见。
我可以返回ContentResult
来指定内容,但无法返回状态码(例如403)和状态描述。我可以使用HttpStatusCodeResult
来指定状态码和状态描述,但不能指定结果内容。
我如何创建一个包含所有三个参数的操作结果?
通常你会看到这样做的方式是设置响应代码,然后返回一个常规的ActionResult。
public ActionResult Foo()
{
Response.StatusCode = 403;
Response.StatusDescription = "Some custom message";
return View(); // or Content(), Json(), etc
}
如果你真的需要将此作为一个ActionResult,你可以创建自己的ActionResult。public class HttpStatusContentResult : ActionResult
{
private string _content;
private HttpStatusCode _statusCode;
private string _statusDescription;
public HttpStatusContentResult(string content,
HttpStatusCode statusCode = HttpStatusCode.OK,
string statusDescription = null)
{
_content = content;
_statusCode = statusCode;
_statusDescription = statusDescription;
}
public override void ExecuteResult(ControllerContext context)
{
var response = context.HttpContext.Response;
response.StatusCode = (int) _statusCode;
if (_statusDescription != null)
{
response.StatusDescription = _statusDescription;
}
if (_content != null)
{
context.HttpContext.Response.Write(_content);
}
}
}
_statusDescription
为空,您可以将其赋值为HttpWorkerRequest.GetStatusDescription(response.StatusCode)
。其背后是在string[][] s_HTTPStatusDescriptions
中进行非常快速的查找,例如s_HTTPStatusDescriptions[StatusCode / 100][StatusCode % 100]
。获取的值始终是状态代码的简短描述,例如“OK”或“Forbidden”,如果没有匹配的描述,则为空字符串。 - Triynko如果这不太脏的话
Response.Clear();
Response.Write("Some specific string");
return new HttpStatusCodeResult(403, "another specific string");
Response.StatusCode = 403; Response.StatusDescription="foo"; return Content("bad request mate");
- drchResponse.Clear();
- Haney在意识到问题是GetAwaiter().OnCompleted(...)之后,我试图让这段代码工作起来,结果把自己逼疯了。这是我最终成功的版本:
public class ApiControllerBase : ApiController
{
...
// Other code
...
public override Task<HttpResponseMessage> ExecuteAsync(HttpControllerContext controllerContext, CancellationToken cancellationToken)
{
return base
.ExecuteAsync(controllerContext, cancellationToken)
.ContinueWith(t =>
{
t.Result.Headers.CacheControl = new CacheControlHeaderValue()
{
NoStore = true,
NoCache = true,
MaxAge = new TimeSpan(0),
MustRevalidate = true
};
t.Result.Headers.Pragma.Add(new NameValueHeaderValue("no-cache"));
t.Result.Content.Headers.Expires = DateTime.Parse("01 Jan 1990 00:00:00 GMT");
return t.Result;
}, cancellationToken);
}
}