如何在MVC3中一起返回状态代码,状态描述和文本?

时间:2021-05-16 21:07:32

From my MVC3 controller action I want to return HTTP 403, set "status description" to some specific string and also return that string in the result content so that it is visible in the browser.

从我的MVC3控制器操作,我想返回HTTP 403,将“状态描述”设置为某个特定字符串,并在结果内容中返回该字符串,以便在浏览器中可见。

I can return ContentResult to specify content, but not a status code (such as 403) and not a status description. I can use HttpStatusCodeResult to specify a status code and status description but not the result content.

我可以返回ContentResult来指定内容,但不能返回状态代码(例如403)而不是状态描述。我可以使用HttpStatusCodeResult指定状态代码和状态描述,但不能指定结果内容。

How do I craft an action result that contains all three?

如何制作包含所有三个的动作结果?

3 个解决方案

#1


15  

Commonly you would see this done by setting the response code then returning a regular ActionResult

通常,您会通过设置响应代码然后返回常规ActionResult来完成此操作

public ActionResult Foo() 
{ 
    Response.StatusCode = 403;
    Response.StatusDescription = "Some custom message";

    return View(); // or Content(), Json(), etc
}

If you really need this to be an ActionResult, you create your own.

如果你真的需要这个作为ActionResult,你可以自己创建。

Example:

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);
        }
    }
}

#2


9  

If this is not too dirty

如果这不是太脏

Response.Clear();
Response.Write("Some specific string");
return new HttpStatusCodeResult(403, "another specific string");

#3


-1  

I went crazy trying to get this code to work before I realized it was the GetAwaiter().OnCompleted(...) that was the problem. Here's the version I got working:

在我意识到它是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);
   }
}

#1


15  

Commonly you would see this done by setting the response code then returning a regular ActionResult

通常,您会通过设置响应代码然后返回常规ActionResult来完成此操作

public ActionResult Foo() 
{ 
    Response.StatusCode = 403;
    Response.StatusDescription = "Some custom message";

    return View(); // or Content(), Json(), etc
}

If you really need this to be an ActionResult, you create your own.

如果你真的需要这个作为ActionResult,你可以自己创建。

Example:

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);
        }
    }
}

#2


9  

If this is not too dirty

如果这不是太脏

Response.Clear();
Response.Write("Some specific string");
return new HttpStatusCodeResult(403, "another specific string");

#3


-1  

I went crazy trying to get this code to work before I realized it was the GetAwaiter().OnCompleted(...) that was the problem. Here's the version I got working:

在我意识到它是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);
   }
}