Create wrapper around response object while still using ODATA

Topics: Web Api
Nov 18, 2011 at 1:46 PM

I'm in my second day using the Web API and love it so far, however I'm trying to get my head around how to handle responses. I wrap every response within this object:

public class WebResult<T>
    {
        public bool Success { get; set; }

        public string ErrorMessage { get; set; }

        public T Result { get; set; }
    }

So a web method would look like so:

[WebGet(UriTemplate = "ReadMessages?authUserId={authUserId}&authGuid={authGuid}&userId={userId}&lastMessageId={lastMessageId}&startDate={startDate}&endDate={endDate}")]
        public WebResult<List<Message>> ReadMessages(int authUserId, string authGuid, uint userId, uint lastMessageId, 
            DateTime startDate, DateTime endDate)
        {
            var result = new WebResult<List<Message>>();
            try
            {
                UserUtility.Authenticate(authUserId, authGuid);

                using (new SessionScope())
                {
                    //get messages.
                    result.Result = (from m in MessageData.FindAll(userId, lastMessageId, startDate, endDate)
                                   select ConvertToView(m)).ToList();
                    result.Success = true;
                }
            }
            catch (Exception exc)
            {
                result.Success = false;
                result.ErrorMessage = exc.ToString();
            }
            return result;
        }

This allows the consuming app to be able to check if the web service call succeeded or not, and if not, to know why (from the error message.) However, for the ODATA to work, I need to return an IQueryable, not my WebResult wrapper object. Is there a way that I can have the best of both worlds?

Coordinator
Nov 18, 2011 at 10:40 PM

The HTTP status code tells you if the request succeeded or not.

For error handling you can use an HttpErrorHandler to control the error response message.

Daniel Roth

Nov 18, 2011 at 10:53 PM

You don't need to put the error handling logic in the service operation itself.  It is cleaner if you use a HttpErrorHandler, as Dan mentioned in the above post.

Here is a good example of how to use the the HttpErrorHandler: 
WCFWebApi\Http\Test\Microsoft.ApplicationServer.Http\Scenarios\HttpConfiguration\AddErrorHandler\

Thanks,
Maggie Ying

Nov 22, 2011 at 3:49 PM

Thanks, this works great.

 

public class WcfHttpErrorHandler : HttpErrorHandler
    {
        protected override bool OnTryProvideResponse(Exception exception, ref HttpResponseMessage message)
        {
            // Describe our exception for the client
            var fault = new RestServiceFault();
            fault.Reason = exception.Message;
            fault.Exception = exception.ToString();

            // Respond with the same request format that was used to invoke the service
            var contentType = HttpContext.Current.Request.ContentType;
            if (string.IsNullOrWhiteSpace(contentType))
                contentType = "application/xml";

            // Send a serialized response to the client
            message = new HttpResponseMessage(HttpStatusCode.InternalServerError)
            {
                Content = new ObjectContent<RestServiceFault>(fault, contentType)
            };

            return true;
        }
    }

var config = new HttpConfiguration() { 
                EnableTestClient = true,
                ErrorHandlers = (handlers, endpoint, descriptions) => handlers.Add(new WcfHttpErrorHandler())
            };