Windows Communication Foundation (WCF) can use two different serialization technologies to turn the data in your application into XML that is transmitted between clients and services, a process called serialization. (datacontract and XML serializer)
By default WCF uses the datacontractserializer class to serialize data types. This serializer supports the following types:
- Primitive types (for example, integers, strings, and byte arrays), as well as some special types, such as xmlelementand datetime, which are treated as primitives.
- Data contract types (types marked with the datacontractattribute ).
- Types marked with the serializableattribute, which include types that implement the iserializable interface.
- Types that implement the ixmlserializable interface.
- Define common collection types, which include custom generic Collection types.
Forbidden. NET Framework types fall into the latter two categories and are thus serializable. arrays of serializable types are also serializable. For a complete list, see specifying data transfer in service contracts.
TheDatacontractserializer, Used together with data contract types, is the recommended way to write new WCF services. For more information, see using data contracts.
When to use the xmlserializer class
WCF also supports the xmlserializer class.XmlserializerClass is not unique to WCF. It is the same serialization engine that ASP. NET web services use.XmlserializerClass supports a much narrower set of types thanDatacontractserializerClass, but allows much more control over the resulting XML and supports much more of the XML Schema Definition Language (XSD) standard. it also does not require any declarative attributes on the serializable types. for more information, see the XML serialization topic in. net Framework documentation. theXmlserializerClass does not support data contract types.
When using svcutil.exe orAdd service referenceFeature in Visual Studio to generate client code for a third-party service, or to access a third-party schema, an appropriate serializer is automatically selected for you. if the schema is not compatible withDatacontractserializer,XmlserializerIs selected.
Manually switching to the xmlserializer
At times, you may have to manually switch toXmlserializer. This happens, for example, in the following cases:
- When migrating an application from ASP. NET web services to WCF, you may want to reuse existing,Xmlserializer-Compatible types instead of creating new data contract types.
- When precise control over the XML that appears in messages is important, but a Web Services Description Language (WSDL) document is not available, for example, when creating a service with types that have to comply to a certain standardized, published schema that is not compatible with the datacontractserializer.
- When creating services that follow the legacy soap encoding standard.
In these and other cases, you can manually switch toXmlserializerClass by applyingXmlserializerformatattributeAttribute to your service, as shown in the following code.
[Servicecontract] [xmlserializerformat] Public Class Bankingservice {[operationcontract] Public Void Processtransaction (bankingtransaction BT ){ // Code not shown. }} // Bankingtransaction is not a data contract class, // But is an xmlserializer-compatible class instead. Public Class Bankingtransaction {[Xmlattribute] Public String Operation;[Xmlelement] Public Account fromaccount; [xmlelement] Public Account toaccount; [xmlelement] Public Int Amount ;} // Notice that the account class must also be xmlserializer-compatible.
TheDatacontractserializerClassOnly serializes membersMarked withDatamemberattributeAttribute when serializing data contract types.XmlserializerClass serializes any public member. See the type in the following code.
[Datacontract]Public ClassCustomer {[datamember]Public StringFirstname; [datamember]Public StringLastname;Public StringCreditcardnumber ;}
If the type is inadvertently used in a service contract whereXmlserializerClass is selected,Creditcardnumber
Member is serialized, which is probably not intended.
Even thoughDatacontractserializerClass is the default, you can explain icitly select it for your service (although doing this shoshould never be required) by applying the datacontractformatattribute attribute to the service contract type.
The serializer used for the service is an integral part of the contract and cannot be changed by selecting a different binding or by changing other configuration settings.
Other important Security considerations Apply to Xmlserializer Class. First, it is strongly recommended that any WCF application that uses Xmlserializer Class is signed with a key that is safeguarded from disclosure. This recommendation applies both when a manual switch to Xmlserializer Is already med and when an automatic switch is already med (by svcutil.exe, add service reference, or a similar tool). This is because Xmlserializer Serialization engine supports the loading Pre-generated serialization assemblies As long as they are signed with the same key as the application. an unsigned application is completely unprotected from the possibility of a malicious Assembly matching the expected name of the pre-generated serialization Assembly being placed in the application folder or the Global Assembly Cache. of course, an attacker must first gain write access to one of these two locations to attempt this action.
Another threat that exists whenever you useXmlserializerIs related to write access to the system Temporary Folder.XmlserializerSerialization engine creates and uses temporarySerialization assembliesIn this folder. You shocould be aware that any process with write access to the Temporary Folder may overwrite these serialization assemblies with malicious code.
Rules for xmlserializer support
You cannot directly applyXmlserializer-Compatible attributes to contract operation parameters or return values. However, they can be applied to typed messages (Message contract body parts), as shown in the following code.
When applied to typed message members, these attributes override properties that conflict on the typed message attributes. For example, in the following code,Elementname
OverridesName
.
[Servicecontract] [xmlserializerformat] Public Class Bankingservice {[operationcontract] Public Void Processtransaction (bankingtransaction BT ){ // Code not shown. } [Messagecontract] Public Class Bankingtransaction {[messageheader] Public String Operation; // This element will be <fromacct> and not <from>: [Xmlelement (elementname = " Fromacct " ), Messagebodymember (name = " From " )] Public Account fromaccount; [xmlelement, messagebodymember] Public Account toaccount; [xmlattribute, messagebodymember] Public Int Amount ;}
The messageheaderarrayattribute is not supported when usingXmlserializer.
Note: |
In this case,XmlserializerThrows the following exception, which is released prior to WCF: "An element declared at the top level of a schema cannot haveMaxoccurs> 1. Provide a wrapper element for 'more' by usingXmlarrayOrXmlarrayitemInsteadXmlelementattribute, Or by using the wrapped parameter style ." If you receive such an exception, investigate whether this situation applies. |
WCFDoes not supportThe soapincludeattribute and xmlincludeattribute attributes in message contracts and operation contracts; Use the knowntypeattribute attribute instead.