0

Using the Web API 2 controller to give data to a web client.

Background:

I had use Visual Studio's "Extract Method" functionality to remove some code that will be re-used elsewhere in my app. Of course, by default it typed everything strongly where possible, and the use case of the extracted method is to automagically enable support for jQGrid's parameters and return a data structure it expects. Knowing I would be using it with more than just a single type of data, I adjusted it to be Generic. It looks like so:

    public class jQGridResult<T>
    {
        int total;
        int page;
        int records;
        List<T> rows;

        public jQGridResult(int totalPages, int page, int totalRecords, IQueryable<T> queryable)
        {
            // TODO: Complete member initialization
            this.total = totalPages;
            this.page = page;
            this.records = totalRecords;
            this.rows = queryable.ToList();
        }
    }

    public static jQGridResult<T> getjQGridResult<T>(int page, int rows, string sidx, string sord, ref IQueryable<T> result)
    {
        int totalRecords = result.Count();
        int totalPages = (int)Math.Ceiling((double)totalRecords / (double)rows);
        //Do some sorting if needed
        if (sord.Length > 0 && sidx.Length > 0)
        {
            if (sord == "desc")
                result = result.OrderByDescending(sidx);
            else
                result = result.OrderBy(sidx);
        }

        jQGridResult<T> jsonData = new jQGridResult<T>
        (
            totalPages,
            page,
            totalRecords,
            result.Skip((page - 1) * rows).Take(rows)
        );
        return jsonData;
    }

Problem:

Returning the results of this object (whether created directly or through the method) via return Ok(jsonData); in the WebApi controller gives me back nothing. (If I return the raw list, this works, but of course isn't in the format wanted).

Am I doing something wrong, or does the helper method Ok() (which creates the IHttpActionResult) not support serializing generic objects?

Tsaukpaetra
  • 579
  • 5
  • 26

1 Answers1

1

Apparently, the default serialization error handling is to return null and not throw anything. Once I tried to serialize manually, I of course, got an error message like: Type 'DCSite.apiTableOutputHelper+jQGridResult`1[DCSite.DAL.SYS_PACKAGE_LOG]' cannot be serialized. Consider marking it with the DataContractAttribute attribute, and marking all of its members you want serialized with the DataMemberAttribute attribute. If the type is a collection, consider marking it with the CollectionDataContractAttribute. See the Microsoft .NET Framework documentation for other supported types."

The solution of course is pretty much laid out in the error text. I just had to decorate everything in the generic class like so:

    [DataContractAttribute]
    public class jQGridResult<T>
    {
        [DataMember]
        int total;
        [DataMember]
        int page;
        [DataMember]
        int records;
        [DataMember]
        List<T> rows;

        public jQGridResult(int totalPages, int page, int totalRecords, IQueryable<T> queryable)
        {
            // TODO: Complete member initialization
            this.total = totalPages;
            this.page = page;
            this.records = totalRecords;
            this.rows = queryable.ToList();
        }
    }

Now everything is peachy again!

Tsaukpaetra
  • 579
  • 5
  • 26