Tuesday, November 24, 2015

WebAPI Headaches

WebAPI is great sometimes, and sometimes can cause you headaches.   I've found that using the format below as a starting point seems to resolve a lot of the problems.
  • Return an HTTPResponseMessage instead of a string.  Otherwise you will see an extra set of quotations around any string you return. 
  • Credentials should be pulled from the header instead of as a parameter on the method. 
  • Set the 'Content' property of the ResponseMessage to any string content you want to return.  If you want to return Json, set this value to 
  • Only use a single parameter on the methods you use. 
  • Use a DTO to pass more complex objects into a POST request. 


using System.Net
using System.Net.Http

 [HttpPost]  
 [Route("MyMethod")]  
 public IHttpActionResult MyMethod()  
 {  
     // check credentials  
     var user = Utility.AuthenticateUserFromHeader(Request.Headers);  
     if (user == null)  
         throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.Unauthorized));  
     var data = Request.Content.ReadAsStringAsync().Result;  
     // process the data   
     return Ok("Response message");  
 }  


Dealing with CORS
Put the following in the Web.config to help with CORS.  (If you like this part, go upvote this guys answer: http://stackoverflow.com/a/36901271/224531)

<httpProtocol>
  <customHeaders>
    <add name="Access-Control-Allow-Origin" value="*" />
    <add name="Access-Control-Allow-Headers" value="Content-Type" />
    <add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS" />
  </customHeaders>
</httpProtocol>
If you have some extra HEADER parameter, you must add it to Access-Control-Allow-Headers, like:
<add name="Access-Control-Allow-Headers" value="Content-Type, X-Your-Extra-Header-Key" />
And finally, to handle OPTIONS requests you must reply with empty response, adding in your application class:
protected void Application_BeginRequest()
{
    if (Request.Headers.AllKeys.Contains("Origin") && Request.HttpMethod == "OPTIONS")
    {
        Response.Flush();
    }
}

No comments:

Post a Comment