webapi odata中的大型json参数
我得到了一个WebApi OData服务,需要一个操作来获取任意json参数 有没有办法将JObject之类的对象作为OData操作参数?webapi odata中的大型json参数,json,asp.net-web-api,odata,Json,Asp.net Web Api,Odata,我得到了一个WebApi OData服务,需要一个操作来获取任意json参数 有没有办法将JObject之类的对象作为OData操作参数? action.Parameter()不起作用 复杂类型“Newtonsoft.Json.Linq.JContainer”通过属性“Parent”对其自身进行引用。不允许复杂类型的递归循环 它使用字符串参数工作,但这意味着所有请求的两端都需要进行不必要的转换。json也可能很大(100kb+),因此我认为它会给大型对象堆带来使用字符串的压力。OData服务通常
action.Parameter()
不起作用
复杂类型“Newtonsoft.Json.Linq.JContainer”通过属性“Parent”对其自身进行引用。不允许复杂类型的递归循环
它使用字符串参数工作,但这意味着所有请求的两端都需要进行不必要的转换。json也可能很大(100kb+),因此我认为它会给大型对象堆带来使用字符串的压力。OData服务通常是强类型的,因此您必须克服Web API从json到CLR类型的内置映射 首先,定义一个读取JTokens的新媒体类型格式化程序。请注意正在使用的自定义媒体类型
public class RawJsonMediaTypeFormatter : MediaTypeFormatter
{
private static readonly MediaTypeHeaderValue _customMediaType =
MediaTypeHeaderValue.Parse("application/prs.adrianm+json");
public RawJsonMediaTypeFormatter() : base()
{
this.Intialize();
}
protected RawJsonMediaTypeFormatter(MediaTypeFormatter formatter) : base(formatter)
{
this.Intialize();
}
protected void Intialize()
{
this.SupportedMediaTypes.Add(_customMediaType);
}
public override MediaTypeFormatter GetPerRequestFormatterInstance(Type type, HttpRequestMessage request, MediaTypeHeaderValue mediaType)
{
if (type == typeof(JToken) && mediaType.MediaType == _customMediaType.MediaType)
{
return this;
}
return base.GetPerRequestFormatterInstance(type, request, mediaType);
}
public override bool CanReadType(Type type)
{
return type == typeof(JToken);
}
public override bool CanWriteType(Type type)
{
return false;
}
public override Task<object> ReadFromStreamAsync(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger)
{
return this.ReadFromStreamAsync(type, readStream, content, formatterLogger, default(CancellationToken));
}
public override Task<object> ReadFromStreamAsync(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger, CancellationToken cancellationToken)
{
object result;
using (var reader = new JsonTextReader(new StreamReader(readStream)))
{
result = JToken.ReadFrom(reader);
}
return Task.FromResult(result);
}
}
为操作添加控制器方法
[HttpPost]
[ODataRoute("ArbitraryJson")]
public IHttpActionResult ArbitraryJson(JToken json)
{
return this.Ok(json.ToString());
}
在客户端上,请记住将内容类型
设置为由自定义格式化程序处理的自定义媒体类型:
POST http://host/ArbitraryJson
Content-Type: application/prs.adrianm+json
[1, 2, {"foo": true }]
响应有效负载应如下所示:
{
"@odata.context": "http://host/$metadata#Edm.String",
"value": "[\r\n 1,\r\n 2,\r\n {\r\n \"foo\": true\r\n }\r\n]"
}
回答得很好。希望我能投更多的票支持你的努力。在我的情况下,对不同内容类型的需求可能会破坏交易,但我确实从你的帖子中学到了很多。谢谢。您可以尝试使用带有额外参数的
application/json
。例如,application/json;格式=原始
。
{
"@odata.context": "http://host/$metadata#Edm.String",
"value": "[\r\n 1,\r\n 2,\r\n {\r\n \"foo\": true\r\n }\r\n]"
}