WCF service returning JSON with an anonymous object

For a simple API I am building I am using a couple of techniques. First of all, this is not my first API I am creating, but it is the first where I have combination of WCF, json and anonymous objects.

I got the following interface for the WCF API:

[ServiceContract]
public interface IAPI
{
    [OperationContract]
    [WebInvoke(Method = "POST",
                 BodyStyle = WebMessageBodyStyle.WrappedRequest,
                 ResponseFormat = WebMessageFormat.Json,
                 RequestFormat = WebMessageFormat.Json)]
    ServiceResponse Authenticate(string username, string hashedPassword);

    [OperationContract]
    [WebInvoke(Method = "POST",
                 BodyStyle = WebMessageBodyStyle.WrappedRequest,
                 ResponseFormat = WebMessageFormat.Json,
                 RequestFormat = WebMessageFormat.Json)]
    ServiceResponse GetProducts();
}

It's all pretty simple, just 2 methods I want to have working. The ServiceResponse class you see there is also really simple, but causing the problems I think:

[DataContract]
public class ServiceResponse
{
    [DataMember]
    public ResponseCode Status { get; set; }

    [DataMember]
    public object Value { get; set; }
}

I made this class, so I can always send a Status (Simple int enum) and an object, for example a string or a list of objects.

I created a small script using jQuery to test my service, and the Authenticate method works like it should, but this method returns a ServiceResponse object, with just a 0 in the Status field. The Value field is left empty here.

The GetProducts method is the one where it gets tricky, an array of anonymous objects like this:

public ServiceResponse GetProducts()
{
       DataClassesDataContext db = new DataClassesDataContext();
       var results = from p in db.Products
                     where p.UserID == 1
                     select new
                     {
                         ID = p.ID,
                         Name = p.DecryptedName
                     };

        return ServiceResponse.OK(results.ToArray());
}

I am using an anonymous type object here, because I do not want to create proxy classes for all the classes I want to use in the API.

When I try out this code, with my simple jQuery script, FireBug tells me that my request has been aborted. I guess this is because of an Error 500 or something. When I put a breakpoint in my GetProducts method, it gets hit 7 times before Firefox says it is aborted and the script is fully run.

Here is the jQuery script I use to test out my WCF service:

$.ajax({
    type: "POST",
    contentType: "application/json; charset=utf-8",
    url: "/Handlers/API.svc/GetProducts",
    data: '{}',
    dataType: "json",
    success: function (response) {
        var test = inspect(response, 5);
        $("#output").html(test);
    },
    error: function (message) {
        $("#output").html(inspect(message, 5));
    }
});

The inspect method you see in there, is just a small JS script that shows me the contents of an object.

I tried the following things to get it moving:

  • Replace the anonymous objects with objects of the type Product, but this failed in the same way
  • Return a List<T> instead of an array, but no luck there either.
  • Returning without anything assigned to the Value property, this worked
  • Changing the property Value to the dynamic type, this failed also

I would love it if I could use WCF to return some sort of array of anonymous objects, because that saves me creating 30+ proxy classes.

NOTE: The Product class is a class generated by LINQ. I am using C# 4.0 for this.

Answers


I may be wrong, but I believe that WCF is fairly strict and will not allow you to return an object the way you are trying to. If you know that the data is going to be an array every time you could change your definition to reflect that (but it sounds like this is not going to work in your case). Otherwise, you might want to consider changing your signature to a simple string and serializing the data into JSON first before returning it.


Need Your Help

Robospice/Maven Intellij Android

maven intellij-idea android-library robospice

I'm trying to get up and running with Robospice for Android.

How to work around the fact that Linq to SQL is using separate SQL DELETE statements for each item in DeleteAllOnSubmit

.net sql linq linq-to-sql deleteallonsubmit

When using a DeleteAllOnSubmit statement like the following (I'm omitting DataContext because I'm using LinqPad here)

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.