使用DataContractJsonSerializer发出odata.type字段?

时间:2013-08-21 20:01:48

标签: json wcf-data-services odata

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

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

有没有办法挂钩DataContractJsonSerializer管道,将所需的“odata.type”字段注入序列化输出?

为了注入字段,必须解析序列化输出。 WCF数据服务如何做到这一点?不使用DataContractJsonSerializer是我的猜测。

2 个答案:

答案 0 :(得分:0)

您是否考虑过使用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; }
}

答案 1 :(得分:0)

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

// 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类型和其他内容,但大多数人最终都采用了反射,这只是为了更复杂的解决方案而不仅仅是使用字符串操作方法