对于我正在构建的简单API,我使用了几种技术。首先,这不是我创建的第一个API,但它是我第一次将WCF,json和匿名对象组合在一起。
我为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();
}
这一切都非常简单,只有两种方法我想要工作。您在那里看到的ServiceResponse
课程也非常简单,但却引发了我认为的问题:
[DataContract]
public class ServiceResponse
{
[DataMember]
public ResponseCode Status { get; set; }
[DataMember]
public object Value { get; set; }
}
我创建了这个类,所以我总是可以发送一个Status(Simple int enum)和一个对象,例如一个字符串或一个对象列表。
我使用jQuery创建了一个小脚本来测试我的服务,Authenticate
方法就像它应该的那样工作,但是这个方法返回一个ServiceResponse
对象,Status
只有0 }字段。此处Value
字段为空。
GetProducts
方法是一个棘手的方法,一个像这样的匿名对象数组:
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());
}
我在这里使用的是匿名类型对象,因为我不想为我想在API中使用的所有类创建代理类。
当我尝试使用我的简单jQuery脚本编写此代码时,FireBug告诉我我的请求已被中止。我想这是因为错误500或其他什么。当我在我的GetProducts
方法中放置一个断点时,它会在Firefox说它被中止并且脚本完全运行之前被点击7次。
这是我用来测试我的WCF服务的jQuery脚本:
$.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));
}
});
你在那里看到的inspect
方法只是一个小的JS脚本,向我展示了一个对象的内容。
我尝试了以下方法来推动它:
Product
类型的对象替换匿名对象,但这种方法失败的方式相同List<T>
而不是数组,但也没有运气。Value
属性的情况下返回,这有效Value
更改为dynamic
类型,此操作也失败如果我可以使用WCF返回某种匿名对象数组,我会很喜欢它,因为这可以节省我创建30多个代理类。
注意:Product
类是LINQ生成的类。我正在使用C#4.0。
答案 0 :(得分:2)
我可能错了,但我相信WCF相当严格,不允许你按照你想要的方式返回对象。如果您知道每次更改定义以反映该数据时数据将成为一个数组(但听起来这在您的情况下不起作用)。否则,您可能需要考虑将签名更改为简单字符串,并在返回之前将数据序列化为JSON。
答案 1 :(得分:0)
简短回答:你不能。您必须使用Web服务,或者 - 如您所说 - 使用代理类。