4xx Response Body

Topics: ASP.NET Web API
Jun 13, 2012 at 9:10 PM

When I create HttpResponseMessages, with status codes 2xx and 5xx, I am able to pass some content in the body. However, when I set a 4xx level status code, the body seems to be ignored. I'm using the RC release. .NET 4.0 and IIS Express.

I have some code that looks like this

 

        [HttpPost]
        public HttpResponseMessage Validate(LogOnModel credentials)
        {
            OperationStatusContext<string> authResult = this.userService.LoginReturnToken(credentials.UserName, credentials.Password);
            if (authResult.IsSuccessful)
            {
                return this.Request.CreateResponse(HttpStatusCode.OK, new UserAuthToken() { Value = authResult.Context });
            }
            else
            {
                //TODO: would prefer to return formatted message                
                var response = this.Request.CreateResponse(HttpStatusCode.Unauthorized, authResult);
                throw new HttpResponseException(response);
            }
        }

OperationStatusContext is a simple object that holds a bool result, string message, and a generic context object. If I change the status code to OK, on the client side , the response body is populated in the correct format. With the a a 401 Unauthorized, the body is empty.

 

Maybe I'm missing something in my settings??

Jun 13, 2012 at 10:59 PM

Hmm, I can't repro this in RC with IIS Express 8 (which comes with RC). With a controller that looks like this:

    public class ValuesController : ApiController
    {
        public HttpResponseMessage Get()
        {
            return Request.CreateResponse<IEnumerable<string>>(HttpStatusCode.Unauthorized, new string[] { "value1", "value2" });
        }

        public HttpResponseMessage Post([FromBody]string value)
        {
            return Request.CreateResponse<string>(HttpStatusCode.Unauthorized, value);
        }
    }

In Fiddler I see something like this for the GET:

HTTP/1.1 401 Unauthorized
Cache-Control: no-cache
Pragma: no-cache
Content-Type: application/json; charset=utf-8
Expires: -1
Server: Microsoft-IIS/8.0
X-AspNet-Version: 4.0.30319
X-SourceFiles: =?UTF-8?B?RDpcUHJvamVjdHNcTXZjQXBwbGljYXRpb24xXE12Y0FwcGxpY2F0aW9uMVxhcGlcdmFsdWVz?=
X-Powered-By: ASP.NET
Date: Wed, 13 Jun 2012 22:56:16 GMT
Content-Length: 19

["value1","value2"]

and this for the POST:

HTTP/1.1 401 Unauthorized
Cache-Control: no-cache
Pragma: no-cache
Content-Type: application/json; charset=utf-8
Expires: -1
Server: Microsoft-IIS/8.0
X-AspNet-Version: 4.0.30319
X-SourceFiles: =?UTF-8?B?RDpcUHJvamVjdHNcTXZjQXBwbGljYXRpb24xXE12Y0FwcGxpY2F0aW9uMVxhcGlcdmFsdWVz?=
X-Powered-By: ASP.NET
Date: Wed, 13 Jun 2012 22:53:51 GMT
Content-Length: 10

"hi there"

Btw, you don't have to throw the exception -- you can just return the response.

Hope this helps,

Henrik

Jun 14, 2012 at 2:32 AM
Edited Jun 14, 2012 at 2:37 AM

I got my service payload working and I was able diagnose the different between the two results.

My original response from Fiddler looked something like this

 

HTTP/1.1 401 Unauthorized
Cache-Control: no-cache
Pragma: no-cache
Content-Type: application/json; charset=utf-8
Expires: -1
Location: /NSUTrivia/Account/Login?ReturnUrl=%2fNSUTrivia%2fapi%2faccounts%2fvalidate
Server: Microsoft-IIS/7.5
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Thu, 14 Jun 2012 02:19:03 GMT
Content-Length: 0

After looking at the location heading I figured somewhere in the ASP.NET pipeline that my response was being intercepted. I changed my web.config

 

FROM
<
authentication mode="Forms"> <forms loginUrl="~/Account/Login" timeout="2880" /> </authentication>

 

TO
<authentication mode="None" />

Now I'm receiving the payload. Is it preferable to not use HttpResponseException and just return the response? What's the difference ?

With regards to the exception. Is it preferable to return the response message as opposed to throw the exception? What's the difference?

Jun 14, 2012 at 2:44 AM

That's great. We have

    <authentication mode="None" />
by default in the template.

HttpResponseException is mostly useful when you have an action that returns an object (i.e. not an HttpResponseMessage). If you already return an HttpResponseMessage then you may as well just return the error response directly.

Thanks!

Henrik

Jun 14, 2012 at 2:58 AM

I started out with an MVC 4 template and not the Web API template. I would like to be able to have service and website in the same project with forms auth turned on. I saw in Haack's post, http://goo.gl/lszOq, he mentions some workarounds that involve creating additional modules, but it looks like these will end up clearing out the body of the request also.

Any chance of there being a better solution for RTM?

 

Thanks for your time.

Coordinator
Jun 20, 2012 at 4:36 AM

We take care of setting up the necessary modules for you in the ASP.NET MVC 4 Release Candidate. Can you please try out the latest bits and see if the body of the request is still getting cleared out?

Daniel Roth