c# - WebApi 2 return types -


i'm looking @ documentation of webapi 2, , i'm severely disappointed way action results architected. hope there better way.

so documentation says can return these:

**void**    return empty 204 (no content)  **httpresponsemessage** convert directly http response message.  **ihttpactionresult**   call executeasync create httpresponsemessage, convert http response message.  **other type**  write serialized return value response body; return 200 (ok). 

i don't see clean way return array of items custom http status code, custom headers , auto negotiated content though.

what see like

public httpresult<item> post() {    var item = new item();    var result = new httpresult<item>(item, httpstatuscode.created);    result.headers.add("header", "header value");     return result; } 

this way can glance on method , see whats being returned, , modify status code , headers.

the closest thing found negotiatedcontentresult<t>, weird signature (why need instance of controller?), there's no way set custom headers?

is there better way ?

i don't think designers of web-api intended controller methods fiddling headers. design pattern seems to use delegatinghandler, actionfilterattribute , executeasync overridable method of apicontroller handle authentication , response formatting.

so perhaps logic message content negotiation should handled there ?

however if need control headers within controller method can little set-up make work. can create own delegationhandler forwards selected headers "inner" response headers:

public class messagehandlerbranding : delegatinghandler {     protected async override task<httpresponsemessage> sendasync(httprequestmessage request, cancellationtoken cancellationtoken)     {         var response = await base.sendasync(request, cancellationtoken);         //if want forward headers inner content can this:         if (response.content != null && response.content.headers.any())         {             foreach (var hdr in response.content.headers)             {                 var keyupr = hdr.key.toupper(); //response not tolerate setting of header values                 if ( keyupr != "content-type" && keyupr != "content-length")                 {                     string val = hdr.value.any() ? hdr.value.firstordefault() : "";                     response.headers.add(hdr.key, val);                                        }             }         }         //add our branding header each response         response.headers.add("x-powered-by", "my product");         return response;     }   } 

then register handler in web-api configuration, in globalconfig.cs file.

config.messagehandlers.add(new messagehandlerbranding()); 

you write own custom class response object this:

public class apiqueryresult<t> : ihttpactionresult t : class {     public apiqueryresult(httprequestmessage request)     {         this.statuscode = httpstatuscode.ok; ;         this.headerstoadd = new list<mystringpair>();         this.request = request;     }      public httpstatuscode statuscode { get; set; }     private list<mystringpair> headerstoadd { get; set; }     public t content { get; set; }     private httprequestmessage request { get; set; }      public void addheaders(string headerkey, string headervalue)     {         this.headerstoadd.add(new mystringpair(headerkey, headervalue));     }      public task<httpresponsemessage> executeasync(cancellationtoken cancellationtoken)     {         var response = this.request.createresponse<t>(this.statuscode, this.content);         foreach (var hdr in this.headerstoadd)         {             response.content.headers.add(hdr.key, hdr.value);          }         return task.fromresult(response);     }       private class mystringpair     {         public mystringpair(string key, string value)         {             this.key = key;             this.value = value;         }         public string key;         public string value;     } } 

and use in controller:

 [httpget]     public apiqueryresult<customersview> customersviewsrow(int id)     {         var ret = new apiqueryresult<customersview>(this.request);         ret.content = this.bll.getonecustomer(id);         ret.addheaders("mycustomhkey","mycustomvalue");         return ret;     } 

Popular posts from this blog