【问题标题】:Create Delta<TSTructuralType> out of a JSON Payload?从 JSON 有效负载中创建 Delta<TSStructuralType>?
【发布时间】:2018-02-06 12:11:34
【问题描述】:

我正在使用 AspNetCore.Odata 7 beta,但基本上这个问题适用于任何 MVC/Web API OData Server 环境。

对于某些要求,我不能像这里那样只使用 Delta 作为参数

 public async Task<IActionResult> Patch(int key, Delta<Car> delta) 

我需要它是一个 JObject(有效),但我必须从 JObject 创建一个 Delta。 然而,我一直在研究 ODataMessageWriter,它具有相当多的依赖性和复杂性。有没有人已经解决了这个谜语?或者只是知道怎么做?

谢谢!

这是一次尝试。但是,OdataSerializerContext 似乎是创建 Delta 的彻底破坏者

 public async Task<IActionResult> Patch(int key, [FromBody] JToken jOb)
    {
        var feature = Microsoft.AspNet.OData.Extensions.HttpContextExtensions.ODataFeature(HttpContext);
        var path = feature.Path;
        var model = feature.Model;
        var context = new ODataDeserializerContext
        {
            Path = path,
            Model = model,
            Request = Request,
            ResourceType = typeof(Car),
            ResourceEdmType = new Microsoft.OData.Edm.EdmEntityTypeReference(new Microsoft.OData.Edm.EdmEntityType("Odata7Test.Models", "Car"), false)
        };

        var dlt = (Delta)Activator.CreateInstance(typeof(Delta<>).MakeGenericType(typeof(Car)));
        var delta = default(Delta<Car>);


        try
        {
            delta = await DeltaCopyUtil.CopyEntityToDelta<Car>(dlt, jOb, context);

        }
        catch (Exception ex)
        {
            Trace.TraceError("Error at Patch {0}", ex);
        }

         public static async Task<Delta<T>> CopyEntityToDelta<T>(Delta delta, JToken jOb, ODataDeserializerContext context) where T: class      
var memStream = new MemoryStream();
var writer = new JsonTextWriter(new StreamWriter(memStream));
await jOb.WriteToAsync(writer);
await writer.FlushAsync();
memStream.Position = 0;

var message = new ODataMessageWrapper(memStream) ;
ODataMessageReader r = new ODataMessageReader((IODataRequestMessage)message);
var lst = ODataInputFormatterFactory.Create();
var myFmt = lst.FirstOrDefault(f => f.SupportedMediaTypes.Contains("application/json"));
var oDataResourceSerializer = new ODataResourceDeserializer(myFmt.DeserializerProvider);        

var obj = oDataResourceSerializer.Read(r, context.ResourceType, context);

return ( Delta < T > )obj;

}

【问题讨论】:

    标签: c# asp.net-core asp.net-web-api2 odata


    【解决方案1】:

    我决定使用内置的 ASP.NET Core JsonPatchDocument 功能,该功能可以与 ODataController PATCH 动词结合使用。这就是我所需要的,我可以忍受使用不同的序列化程序(因此,不使用 EDMModel),并且客户端必须遵守与 OData 补丁完全不同的 IETF RFC 6901。

    那就是:

    public async Task<IActionResult> Patch(int key, [FromBody] JSonPatchDocument<Car> delta)
    

    但我需要一些东西来保存 JSON 并在另一个地方重建对象。

      public async Task<IActionResult> Patch(int key, [FromBody] JToken deltaObj2) 
        {
            var jc = new Microsoft.AspNetCore.JsonPatch.Converters.JsonPatchDocumentConverter();
            var mem = new MemoryStream();
            var jw = new JsonTextWriter(new StreamWriter(mem));
            deltaObj2.WriteTo(jw);
            jw.Flush();
            mem.Position = 0;
            var jt = new JsonTextReader(new StreamReader(mem));
    
            var deltaObj = (JsonPatchDocument)jc.ReadJson(jt, typeof(JsonPatchDocument), new Car(), new JsonSerializer());
    
            var origCar = products.FirstOrDefault(f => f.Id == key);
            deltaObj.ApplyTo(origCar);
            TryValidateModel(origCar);
    
    
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState.SelectMany(s => s.Value.Errors.Select(x => x.Exception.Message)));
            }
            return Updated(origCar);
        }   
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-07-23
      • 2015-01-16
      • 2018-07-22
      • 2020-11-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多