Search code examples
serializationodatajsonconvert

Simple serialize ODataQueryOptions


I'm trying to:

    [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);
    }

But got

Newtonsoft.Json.JsonSerializationException: 'Error getting value from 'ReadTimeout' on 'Microsoft.Owin.Host.SystemWeb.CallStreams.InputStream'.'

"Timeouts are not supported on this stream."

I know there is already a question about serialize Stream:

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

But in this case i can't "extract stream value" from ODataQueryOptions, or can I?

Some ideia?


Solution

  • Since we work on the same company, if anyone is interested, we found a way, maybe not the pretty way, to serialize an 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
            };
        }
    

    After you serialize it to an object you can serialize it to a JSON string:

        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);