Я нашел хорошее решение этой проблемы, которое позволяет вам внедрить свой собственный XmlSerializer в WCF, который используется при сериализации и десериализации запросов. Этот XmlSerializer можно настроить так, чтобы он полностью пропускал пространства имен XML (включая xmlns:i="w3.org/2001/XMLSchema-instance"
) или любым другим способом.
Мое решение использует WcfRestContrib . Вы можете почти использовать включенный POX форматтер , но в нашем случае мы хотели поддерживать атрибуты, поэтому мы написали наш собственный простой форматер.
Инструкция:
1) Ссылка WcfRestContrib из вашего проекта.
2) Создать IWebFormatter
реализацию:
public class NamespacelessXmlFormatter : IWebFormatter {
public object Deserialize(WebFormatterDeserializationContext context, Type type) {
if (context.ContentFormat != WebFormatterDeserializationContext.DeserializationFormat.Xml) {
throw new InvalidDataException("Data must be in xml format.");
}
return NamespacelessXmlSerializer.Deserialize(context.XmlReader, type);
}
public WebFormatterSerializationContext Serialize(object data, Type type) {
using (var stream = NamespacelessXmlSerializer.Serialize(data, type)) {
using (var binaryReader = new BinaryReader(stream)) {
byte[] bytes = binaryReader.ReadBytes((int)stream.Length);
return WebFormatterSerializationContext.CreateBinary(bytes);
}
}
}
}
Который использует XmlSerializer, который соответствует вашим потребностям (вот наш, который просто пропускает все пространства имен):
public static class NamespacelessXmlSerializer {
private static readonly XmlSerializerNamespaces _customNamespace = new XmlSerializerNamespaces();
private static readonly XmlWriterSettings _xmlSettings = new XmlWriterSettings {
OmitXmlDeclaration = true
};
static NamespacelessXmlSerializer() {
// to make sure .NET serializer doesn't add namespaces
_customNamespace.Add(String.Empty, String.Empty);
}
/// <summary>
/// Deserializes object from its XML representation.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="stream"></param>
/// <returns></returns>
public static T Deserialize<T>(Stream stream) {
return (T)Deserialize(stream, typeof(T));
}
/// <summary>
/// Deserializes object from its XML representation.
/// </summary>
public static object Deserialize(Stream stream, Type type) {
var ds = new XmlSerializer(type);
var d = ds.Deserialize(stream);
return d;
}
public static object Deserialize(XmlDictionaryReader xmlReader, Type type) {
var ds = new XmlSerializer(type);
var d = ds.Deserialize(xmlReader);
return d;
}
/// <summary>
/// Serializes object to XML representation.
/// </summary>
/// <exception cref="InvalidOperationException">
/// Is thrown when there was an error generating XML document. This can happen
/// for example if the object has string with invalid XML characters:
/// http://www.w3.org/TR/2004/REC-xml-20040204/#charsets.
/// See this article for other potential issues:
/// http://msdn.microsoft.com/en-us/library/aa302290.aspx
/// </exception>
public static Stream Serialize<T>(T objectToSerialize) {
return Serialize(objectToSerialize, typeof(T));
}
/// <summary>
/// Serializes object to XML representation.
/// </summary>
/// <exception cref="InvalidOperationException">
/// Is thrown when there was an error generating XML document. This can happen
/// for example if the object has string with invalid XML characters:
/// http://www.w3.org/TR/2004/REC-xml-20040204/#charsets.
/// See this article for other potential issues:
/// http://msdn.microsoft.com/en-us/library/aa302290.aspx
/// </exception>
public static Stream Serialize(object objectToSerialize, Type type) {
var stream = new MemoryStream();
XmlWriter writer = XmlWriter.Create(stream, _xmlSettings);
var x = new XmlSerializer(type);
x.Serialize(writer, objectToSerialize, _customNamespace);
stream.Position = 0;
return stream;
}
}
3) Примените атрибуты WebDispatchFormatter...
к вашему сервису, используя вашу пользовательскую реализацию в качестве типа (на основе этой документации ):
[WebDispatchFormatterConfiguration("application/xml")]
[WebDispatchFormatterMimeType(typeof(NamespacelessXmlFormatter), "application/xml")]
4) Примените атрибут WebDispatchFormatter
ко всем вашим методам обслуживания (на основе этой документации ).
5) Вот и все. Протестируйте свой сервис и подтвердите, что теперь он работает так, как ожидалось.