Web API–How to change Default Serializer settings

Out of box, Web API provides a way to serialize using JSON and XML.
In this blog post, I will describe how you can control JSON settings for the default serializer.

JSON Settings.

e.g Say you want your date to be formatted as per Microsoft format as opposed to ISO standard (for whatever reason).
All you do is get hold of the jsonFormatter and then use SerializerSettings to set DateFormatHandling.

JsonDateFormatCode

ISO Date Format for JSON

isoFormat

Microsoft Date Format for JSON.

microsoftdateFormat

By default, Json.NET will use ISO format for your date time format serialization

Advertisements

WebAPI: Calculating NextPageLink for ODataResult<>

Fall update of Web API introduced ODataResult<> which is used to implement OData features like Server Driven Paging and $inlinecount. I blogged about it here 

If you look at the definition of ODataResult<>, it has following properties,

1. Items Collection
2. NextPageLink property
3. Count

Essentially calculating Items and Count are no brainer once you have access to IQueryable however NextPageLink can be interesting as there is no default implementation.

In this post, I’m going to describe how to calculate NextPageLink property. Feel free to modify the code as per your requirement, it is merely one way of achieving the goal.

Basics:

If you think about Paging support, you are thinking of two possible parameters, Batch Size & Page Number.

Usually queries are done like pageNumber=1 & batchSize=2 for first page, pageNumber=2 & batchSize=2 for the next page and so on, resulting in request made for page from 1..N but your batchSize does not change.

Here is the complete code sample which shows you how to calculate the NextPageLink.

 public static Uri CalculateNextPageLink(
            HttpRequestMessage request,
            int resultLimit)
        {
            if (resultLimit <= 0)
            {
                return null;
            }

            int topValue;
            int skipValue;

            var topValueRaw = request.GetQueryNameValuePairs()
                                     .FirstOrDefault(x => x.Key == "$top");
            if (!Int32.TryParse(
                topValueRaw.Value,
                out topValue))
            {
                return null;
            }

            var skipValueRaw = request.GetQueryNameValuePairs()
                                      .FirstOrDefault(x => x.Key == "$skip");

            if (!Int32.TryParse(
                skipValueRaw.Value,
                out skipValue))
            {
                return null;
            }

            if ((topValue > resultLimit) || (topValue <= 0 || skipValue < 0))
            {
                //return the same url
                return null;
            }

            //logic
            //skip=pageIndex*pageSize
            //top=pageSize
            var stringBuilder = new StringBuilder();
            var bothSkipAndTopSupplied = (topValue != -1 && skipValue != -1);
            var lastPageIndex = skipValue/topValue;
            //int lastPageNumber = lastPageIndex+1;

            foreach (var keyValue in request.GetQueryNameValuePairs())
            {
                switch (keyValue.Key)
                {
                    case "$top":
                        stringBuilder.AppendFormat("$top={0}",(bothSkipAndTopSupplied)? topValueRaw.Value: keyValue.Value);
                        break;
                    case "$skip":
                        if ((bothSkipAndTopSupplied))
                        {
                            stringBuilder.AppendFormat("$skip={0}",((lastPageIndex + 1)*topValue));
                        }
                        else
                        {
                            stringBuilder.AppendFormat("$skip={0}",keyValue.Value);
                        }
                        break;
                    default:
                        stringBuilder.Append(Uri.EscapeUriString(keyValue.Key));
                        stringBuilder.Append("=");
                        stringBuilder.Append(Uri.EscapeDataString((keyValue.Value)));
                        break;
                }

                stringBuilder.Append("&");
            }

            stringBuilder.Remove(
                stringBuilder.Length - 1,
                1);

            return new UriBuilder(request.RequestUri)
            {
                Query = stringBuilder.ToString()
            }.Uri;
        }