C# 如何在REST WCF服务中接受任意JSON对象?
我想实现如下服务方法:C# 如何在REST WCF服务中接受任意JSON对象?,c#,.net,json,wcf,rest,C#,.net,Json,Wcf,Rest,我想实现如下服务方法: [OperationContract] [WebInvoke(RequestFormat = WebMessageFormat.Json, ResponseFormat=WebMessageFormat.Json)] public void MakeShape(string shape, string color, IDictionary<string, object> moreArgs) { if (shape == "circle") {
[OperationContract]
[WebInvoke(RequestFormat = WebMessageFormat.Json, ResponseFormat=WebMessageFormat.Json)]
public void MakeShape(string shape, string color, IDictionary<string, object> moreArgs)
{
if (shape == "circle")
{
MakeCircle(color, moreArgs);
}
}
在调用MakeCircle时,moreArgs将有3个条目(“radius”、“filled”和一个名为“annotation”的字典,其中包含2个键值对。)
到目前为止,我得到的最好结果是:
//Step 1: get the raw JSON by accepting a Stream with BodyStyle=WebMessageBodyStyle.Bare
[OperationContract]
[WebInvoke(RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, BodyStyle=WebMessageBodyStyle.Bare)]
public void MakeShape(Stream jsonStream)
{
//Step 2: parse it into a Dictionary with JavaScriptSerializer or JSON.net
StreamReader reader = new StreamReader(jsonStream);
JavaScriptSerializer jsSerializer = new JavaScriptSerializer();
Dictionary<string, object> args = jsSerializer.Deserialize<Dictionary<string,object>>(reader.ReadToEnd());
//Step 3: manually lookup and cast the "standard" arguments, and remove them from the Dictionary
string shape = (string)args["shape"];
string color = (string)args["color"];
//Step 4: make the original call, passing the remaining Dictionary as moreArgs
MakeShape(shape,color,args);
}
这并不理想,但我可以接受。问题变成了如何定义更多参数并正确填充一个参数。我的下一次尝试:
[DataContract]
public class MoreArgs : ISerializable
{
public Dictionary<string, object> Properties;
public MoreArgs(SerializationInfo info, StreamingContext context)
{
Properties = new Dictionary<string, object>();
foreach (var entry in info)
{
Properties.Add(entry.Name, entry.Value);
}
}
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
foreach (string key in Properties.Keys)
{
info.AddValue(key, Properties[key]);
}
}
}
[DataContract]
公共类MoreArgs:ISerializable
{
公共字典属性;
public MoreArgs(SerializationInfo信息、StreamingContext上下文)
{
属性=新字典();
foreach(信息中的var条目)
{
添加(entry.Name、entry.Value);
}
}
public void GetObjectData(SerializationInfo信息、StreamingContext上下文)
{
foreach(Properties.Keys中的字符串键)
{
info.AddValue(key,Properties[key]);
}
}
}
这会在服务启动时引发InvalidDataContractException(…MoreArgs'无法ISerializable且具有DataContractAttribute属性。)
移除[DATACONTROR]属性抛出ValudDATAcNoTractExtExchange,我预期(……MyErgS)不能被序列化。考虑用DATACONTROTTABLE属性……标记它)。< /P> 正如预期的那样,删除ISerializable继承会清除异常,但会导致调用MakeCycle时moreArgs.Properties为null
我还想知道是否有一些混合解决方案我可以使用?也许:
- 接受一个流并像我第一次尝试那样构造参数字典
- 像我稍后的尝试一样,使用MoreArgs参数定义方法
- 从从流中提取的字典中填充MoreArgs对象
- 以某种方式重新调用WCF,说“调用如果有这些参数将被调用的方法”(指定原始参数字典,加上新的正确填充的MoreArgs)
如果后期绑定是一个性能问题,我会考虑把所有的调用手动放在一个大交换机(MultDead)中。如果我的接口仍在频繁更改,我可能会尝试生成样板绑定代码作为构建步骤。也许我再也不会麻烦了,因为我在DB访问方面会遇到瓶颈。
你有没有想过解决这个问题的办法?这是我遇到的一个用例,我也遇到过同样的情况。我最终接受了一个流作为请求参数,并使用JSON.NET解析流中包含的JSON对象。谢谢你跟进你自己的问题+1.{
"shape":"circle",
"color": "blue",
"moreArgs":{
"radius": 42,
"filled":true
"annotation": {"date":"1/1/2012", "owner":"George"}
}
}
[DataContract]
public class MoreArgs : ISerializable
{
public Dictionary<string, object> Properties;
public MoreArgs(SerializationInfo info, StreamingContext context)
{
Properties = new Dictionary<string, object>();
foreach (var entry in info)
{
Properties.Add(entry.Name, entry.Value);
}
}
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
foreach (string key in Properties.Keys)
{
info.AddValue(key, Properties[key]);
}
}
}