Lollo
Lollo

Reputation: 615

ASP.NET WebApi ApiController change StatusCode

I have a RESTful service in .NET and i would like all actions return an object of type JsonResult, JsonResult is an object defined by me like this:

public class JsonResult<T>
{
    public Notify Notify {get; set;}
    public T Data {get; set;}

    public static CreateResponse(T Data, Notify Notify = null, HttpStatusCode Code = HttpStatusCode.OK)
    {
        //Code param not manage, at the moment

        return new JsonResult<T>
        {
            Data = Data,
            Notify = Notify
        };

    }
}

public class Notify
{
    public string Message {get; set;}
    public Severity Severity {get; set;}
}

public enum Severity
{
    Error,
    Info,
    Warning,
    Fatal,
}

so at the moment i have actions look like that:

public JsonResult<string> Get()
{

    return JsonResult<string>.CreateResponse("Ciao Mondo!");
}

it works and i like this form 'cause when i read the firm i already know what i want to return to the client (JsonResult, T is the type of my data)... but the problem is when i want to manage the status code.

Before to create this new project, to manage the status code i used the HttpResponseMessage and the method Request.CreateResponse to return some data to the client:

public HttpResponseMessage Get()
{

    return Request.CreateResponse(HttpStatusCode.BadRequest, "Ciao Mondo!");
}

but i don't like that 'cause it is not immediate to know the returned type.

so... my question is... how can i manage the status code into my JsonResult.CreateResponse(T, Notify[, HttpStatusCode]) method?

this method is moved into an CustomApiController (inherits from ApiController), so i have HttpContext and Request available.

Thanks so much to all

Upvotes: 2

Views: 1109

Answers (3)

Lollo
Lollo

Reputation: 615

Your answer were be very helpful. I was looking for another solution, but you gave me a good idea and i have found this solution:

public class CustomApiController : ApiController
{

    public class JsonResult<Target> : NegotiatedContentResult<Target>
    {
        public JsonResult(HttpStatusCode statusCode, Json<Target> content, ApiController controller) : base(statusCode, content.Data, controller)
        {

            this.Content = content;
        }

        public JsonResult(HttpStatusCode statusCode, Target content, ApiController controller) : base(statusCode, content, controller)
        {

        }

        public JsonResult(HttpStatusCode statusCode, Target content, IContentNegotiator contentNegotiator, HttpRequestMessage request, IEnumerable<MediaTypeFormatter> formatters)
            : base(statusCode, content, contentNegotiator, request, formatters)
        {

        }

        public new Json<Target> Content { get; private set; }

    }


    public JsonResult<Target> CreateResponse<Target>(Target Data, string Notify, HttpStatusCode Code = HttpStatusCode.OK)
    {
        Json<Target> json = new Json<Target>
        {
            Notify = Notify,
            Data = Data
        };

        return new JsonResult<Target>(Code, json, this);
    }

}

so i can inherit from CustomApiController and write action like that:

    public JsonResult<IEnumerable<string>> Get(bool test)
    {
        if (test)
        {
            return this.CreateResponse(new string[] { "test1", "test2", "test3" } as IEnumerable<string>, null, System.Net.HttpStatusCode.OK);
        }
        else
        {
            return this.CreateResponse(new string[] { "test1", "test2", "test3" } as IEnumerable<string>, null, System.Net.HttpStatusCode.BadRequest);
        }
    }

thanks a lot!

Upvotes: 0

user2331950
user2331950

Reputation:

Its preferred to use IHttpActionResult, don't forcefully define it to JsonResult. This should be configurable through content-negotiation.

You can try as below:

     public IHttpActionResult Get()
     {
      if(error)
          BadRequest("Bad Request !!");
       return Ok("Ciao Mondo!");
     }

Upvotes: 0

Igor
Igor

Reputation: 62213

You could call Content which accepts a HttpStatusCode as well as a generic object. It does require you to change your method's return type to IHttpActionResult which is generally preferred.

public IHttpActionResult Get()
{
  if(someErrorCondition)
     return Content(HttpStatusCode.BadRequest, JsonResult<string>.CreateResponse("Ciao Mondo!"));
  return Ok(JsonResult<string>.CreateResponse("Ciao Mondo!"));
}

Upvotes: 2

Related Questions