Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
webapi odata中的大型json参数_Json_Asp.net Web Api_Odata - Fatal编程技术网

webapi odata中的大型json参数

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服务通常

我得到了一个WebApi OData服务,需要一个操作来获取任意json参数

有没有办法将JObject之类的对象作为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]"
}