【问题标题】:Emit odata.type field with DataContractJsonSerializer?使用 DataContractJsonSerializer 发出 odata.type 字段?
【发布时间】:2013-08-21 20:01:47
【问题描述】:

有没有办法让DataContractJsonSerializer 在将 OData 实体发布到支持多种实体类型(每个表的层次结构)的集合中时发出所需的“odata.type”字段?

如果我使用将 EmitTypeInformation 设置为 Always 的设置对象构造 DataContractJsonSerializer,它会在输出中发出“__type”字段,但这不是 OData 所需的字段名称,值的格式是也错了。

有什么方法可以连接到DataContractJsonSerializer 管道,将所需的“odata.type”字段注入到序列化输出中?

必须解析序列化输出才能注入该字段,这将是一种黑客行为。 WCF 数据服务是如何做到的?我猜不使用DataContractJsonSerializer

【问题讨论】:

    标签: json wcf-data-services odata


    【解决方案1】:

    您是否考虑过使用Json.Net? Json.Net 更具可扩展性,您可以使用自定义解析器来完成您所拥有的场景。示例代码

    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine(
                JsonConvert.SerializeObject(new Customer { Name = "Raghu" }, new JsonSerializerSettings
                {
                    ContractResolver = new CustomContractResolver()
                }));
        }
    }
    
    public class CustomContractResolver : DefaultContractResolver
    {
        protected override JsonObjectContract CreateObjectContract(Type objectType)
        {
            JsonObjectContract objectContract = base.CreateObjectContract(objectType);
            objectContract.Properties.Add(new JsonProperty
            {
                PropertyName = "odata.type",
                PropertyType = typeof(string),
                ValueProvider = new StaticValueProvider(objectType.FullName),
                Readable = true
            });
    
            return objectContract;
        }
    
        private class StaticValueProvider : IValueProvider
        {
            private readonly object _value;
    
            public StaticValueProvider(object value)
            {
                _value = value;
            }
    
            public object GetValue(object target)
            {
                return _value;
            }
    
            public void SetValue(object target, object value)
            {
                throw new NotSupportedException();
            }
        }
    }
    
    public class Customer
    {
        public string Name { get; set; }
    }
    

    【讨论】:

    • 如果所涉及的数据类型复杂而深入,我可能会求助于第三方库。我们的数据类型简单而浅薄,因此我可以使用一些拼凑在一起的字符串 concat 来手动发出所需的 JSON。令我恼火的是,WCF 以我需要的方式发出 JSON,但我不知道如何让它也为我做到这一点。当我想要做的代码已经在我的进程中时,我宁愿不依赖另一个外部库,我只是不知道如何得到它。
    【解决方案2】:

    我无法回答您的前两个问题,但对于第三个问题,我在OData Team blog 上找到了指向OData WCF Data Services V4 library open source code 的链接。下载该代码,您将看到它们手动执行所有序列化和反序列化。他们的两个 Json 文件夹中有 68 个文件!并查看他们有 cmets 的代码,例如:

    // This is a work around, needTypeOnWire always = true for client side: 
    // ClientEdmModel's reflection can't know a property is open type even if it is, so here 
    // make client side always write 'odata.type' for enum.
    

    所以对我来说,这意味着没有简单、干净、简单、优雅的方式来做到这一点。

    我尝试使用JavaScriptConverterdynamic 类型和其他东西,但其中大多数最终都求助于使用反射,与仅使用字符串操作方法相比,它的解决方案要复杂得多。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-08-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多