Reputation: 5998
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:
Product
, but this failed in the same wayList<T>
instead of an array, but no luck there either.Value
property, this workedValue
to the dynamic
type, this failed alsoI 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.
Upvotes: 4
Views: 4345
Reputation: 1972
Short answer: You can't. You have to use web services instead or -as you said- use a proxy class.
Upvotes: 0
Reputation: 6331
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.
Upvotes: 2