简体   繁体   English

使用WCF将类序列化为xsd.exe生成的JSON

[英]Serializing a class to JSON generated by xsd.exe using WCF

I want to write a RESTful Webservice with WCF which is able to reply in JSON and XML. 我想用WCF编写RESTful Webservice,它能够以JSON和XML进行回复。 I have a XML schema from which I generated my classes by using xsd.exe . 我有一个XML模式,我通过使用xsd.exe生成我的类。 Everthing works fine as long as I request XML, but it fails if I want JSON as response. 只要我请求XML,Everthing就可以正常工作,但如果我想要JSON作为响应,它就会失败。

The System.ServiceModel.Dispatcher.MultiplexingDispatchMessageFormatter throws a System.Collections.Generic.KeyNotFoundException . System.ServiceModel.Dispatcher.MultiplexingDispatchMessageFormatter抛出System.Collections.Generic.KeyNotFoundException The problem is, what I found out so far, that xsd.exe does not generate DataContract and DataMember Attributes. 问题是,到目前为止我发现, xsd.exe不生成DataContractDataMember属性。 Is there any solution to this where I do not need to use the SvcUtil.exe , because therefore I would need to change my schema.. 是否有任何解决方案,我不需要使用SvcUtil.exe ,因为我需要更改我的架构..

That is the code where it fails, JsonDispatchMessageFormatter is of the type MultiplexingDispatchMessageFormatter . 这是失败的代码, JsonDispatchMessageFormatter的类型为MultiplexingDispatchMessageFormatter (Which is the default type anyway) (无论如何,这是默认类型)

var headers = requestProperty.Headers[HttpRequestHeader.Accept] ?? requestProperty.Headers[HttpRequestHeader.ContentType];
if (headers != null && headers.Contains("application/json"))
{
    return this.JsonDispatchMessageFormatter.SerializeReply(messageVersion, parameters, result);
}

Generated code: 生成的代码:

[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.33440")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(Namespace="...")]
[System.Xml.Serialization.XmlRootAttribute(Namespace="...", IsNullable=false)]
public partial class Incident {        
    private long incidentIdField;

    /// <remarks/>
    public long IncidentId {
        get {
            return this.incidentIdField;
        }
        set {
            this.incidentIdField = value;
        }
    }
}

The reason you are seeing private fields rather than public properties in your JSON is that xsd.exe has marked your classes with [SerializableAttribute] . 您在JSON中看到私有字段而不是公共属性的原因是xsd.exe已使用[SerializableAttribute]标记了您的类。 When this attribute is applied to a type, it signifies that instances of the type can be serialized by serializing all private and public fields -- not the properties. 将此属性应用于某个类型时,它表示可以通过序列化所有私有字段和公共字段 (而不是属性)来序列化该类型的实例。

Under the covers, WCF uses DataContractJsonSerializer to serialize to and from JSON. 在封面下,WCF使用DataContractJsonSerializer与JSON进行序列化。 When this serializer goes to generate a default, implicit data contract for a type without data contract attributes , it notices the [Serializable] attribute and respects it, generating a contract to serialize and deserialize public and private fields. 当此序列化程序为没有数据协定属性的类型生成默认的隐式数据协定时,它会注意到[Serializable]属性并尊重它,生成一个序列化和反序列化公共和私有字段的合同。 This is what you are seeing. 这就是你所看到的。

What is a bit odd is that xsd.exe doesn't need to add [Serializable] to its generated classes. 有点奇怪的是, xsd.exe不需要将[Serializable]添加到其生成的类中。 XmlSerializer completely ignores this attribute since it can only serialize public members . XmlSerializer 完全忽略此属性,因为它只能序列化公共成员 (It also completely ignores data contract attributes. Similarly the data contract serializers all ignore XmlSerializer control attributes .) (它也完全忽略了数据契约属性。类似地,数据契约序列化器都忽略了XmlSerializer控件属性 。)

Unfortunately, I don't see any xsd command line switches to disable this attribute. 不幸的是,我没有看到任何xsd命令行开关来禁用此属性。 Thus you're going to do some sort of manual fix: 因此,您将要进行某种手动修复:

As an aside, WCF rest may not be the best technology for you if you want precise control over your XML and JSON formatting. 另外,如果您想要精确控制XML和JSON格式,WCF休息可能不是最适合您的技术。 ASP.NET Web API allows for much more precise control of serialization formats by using ; ASP.NET Web API允许使用更精确地控制序列化格式; see JSON and XML Serialization in ASP.NET Web API along with Setting IgnoreSerializableAttribute Globally in Json.net and .NET WebAPI Serialization k_BackingField Nastiness . 请参阅ASP.NET Web API中的JSON和XML序列化以及在Json.net.NET WebAPI序列化k_BackingField Nastiness中 全局设置IgnoreSerializableAttribute

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM