【问题标题】:Simple serialize ODataQueryOptions简单序列化 ODataQueryOptions
【发布时间】:2019-10-29 05:00:03
【问题描述】:

我正在尝试:

    [EnableQuery]
    [HttpGet]
    [ODataRoute("")]
    public IHttpActionResult Get(ODataQueryOptions<UserODataModel> options)
    {
        var users = _repository.RetrieveOData();
       
        var serialQuery = JsonConvert.SerializeObject(options, jsonOptions);
        
        //save serialQuery somewhere

        return Ok(users);
    }

得到了

Newtonsoft.Json.JsonSerializationException:'从'Microsoft.Owin.Host.SystemWeb.CallStreams.InputStream'上的'ReadTimeout'获取值时出错。'

“此流不支持超时。”

我知道已经有一个关于序列化 Stream 的问题:

Newtonsoft Json.net - how to serialize content of a stream?

但在这种情况下,我不能从ODataQueryOptions“提取流值”,或者我可以吗?

有什么想法?

【问题讨论】:

  • 你真的需要序列化整个选项对象吗?它非常复杂,毫无疑问,它包含的东西比你真正需要的要多得多。对您的问题的一个更简单的答案可能是定义一个新对象,您可以将所需的相关选项数据复制到该对象中,并且就是您序列化的那个实例。

标签: serialization odata jsonconvert


【解决方案1】:

由于我们在同一家公司工作,如果有人感兴趣,我们找到了一种方法,也许不是很好的方法来序列化 ODataQueryOptions:

    public static ODataQueryOptions DeserializeQueryOptions(SerializedQueryOptions options)
    {
        var uri = new Uri(teste.OriginalUri);
        var model = ODataConfig.Model; //GetEdmModel
        var segment = model.EntityContainer.FindEntitySet(options.EdmType);
        var newPath = new Microsoft.AspNet.OData.Routing.ODataPath(new EntitySetSegment(segment));

        var httpConfiguration = new HttpConfiguration();
        httpConfiguration.EnableDependencyInjection();
        var request = new HttpRequestMessage(HttpMethod.Get, uri)
        {
            Properties =
            {
                { HttpPropertyKeys.HttpConfigurationKey, httpConfiguration },
            }
        };

        var context = new ODataQueryContext(model, options.EntityType, newPath);
        var oDataQueryOptions = new ODataQueryOptions(context, request);

        return oDataQueryOptions;
    }

    public static SerializedQueryOptions SerializeQueryOptions(ODataQueryOptions options)
    {
        return new SerializedQueryOptions
        {
            OriginalUri = options.Request.RequestUri.AbsoluteUri,
            EdmType = options.Context.NavigationSource.Name,
            EntityType = options.Context.ElementClrType
        };
    }

将其序列化为对象后,可以将其序列化为 JSON 字符串:

    var queryOptionsSerialized = new SerializedQueryOptions()
    {
        OriginalUri = "http://localhost:25723/odata/users?$skip=0&$top=2&$orderby=fullName&$count=true",
        EdmType = "users",
        EntityType = typeof(UserODataModel)
    };

    var json = JsonConvert.SerializeObject(queryOptionsSerialized);
    var deserialized = JsonConvert.DeserializeObject<SerializedQueryOptions>(json);

    var options = ODataQueryOptionsHelper.DeserializeQueryOptions(deserialized);

【讨论】:

    【解决方案2】:

    如果 One 不使用 OData 路由或使用 ApiController(不是 ODataController), 修改ODataPath的获取方式为:

    ODataUriParser parser = new ODataUriParser(model, serviceRoot, requestUri);
    ODataPath path = parser.ParsePath();
    //var newPath = new Microsoft.AspNet.OData.Routing.ODataPath(new EntitySetSegment(segment));
    Microsoft.AspNet.OData.Routing.ODataPath newPath = new Microsoft.AspNet.OData.Routing.ODataPath(path.FirstOrDefault());
    

    其中 serviceRoot 是除模型中定义的路径之外的 Url 部分。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-12-25
      • 2015-05-18
      • 2020-07-10
      • 2010-12-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多