Десериализация XML работает только с пространством имен в xml

Самый простой способ заставить десериализацию ServiceStack xml работать — это когда xml содержит пространство имен. Однако XML, который я получаю, не содержит пространств имен. Самый простой рабочий пример:

[Serializable]
public class test
{

}

class Program
{
   static void Main(string[] args)
   {
       string xml="<test xmlns=\"http://schemas.datacontract.org/2004/07/\"></test>";
       var result = ServiceStack.Text.XmlSerializer.DeserializeFromString<test>(xml);
   }
}

Однако это не то, чего я хочу. Я хочу десериализовать следующее, так как это xml, который я получаю от нескольких сервисов:

string xml="<test></test>";

Но это дает мне следующую ошибку:

DeserializeDataContract: Error converting type: Error in line 1 position 7. 
Expecting element 'test' from namespace 
'http://schemas.datacontract.org/2004/07/'.. 
Encountered 'Element'  with name 'test', namespace ''.

Я старался:

[Serializable]
[XmlRoot("test", Namespace = "")]
public class test

Я не могу создать новый сериализатор, потому что ServiceStack.Text.XmlSerializer является статическим. Мне нужно выбрать либо Microsoft XmlSerializer, либо ServiceStack (не оба). Значение: если я не могу заставить этот простой пример работать, мне нужно пропустить очень полезную часть пакета ServiceStack. Последнее, что я хочу, это ввести какое-то фиктивное пространство имен во входящий xml.


person user1154148    schedule 13.03.2012    source источник


Ответы (1)


ServiceStack использует Xml DataContractSerializer .NET для сериализации XML для удаления пространств имен, которые вам нужны, чтобы либо установить пространство имен в пустую строку с помощью:

[DataContract(Namespace="")]
public class test { ... }

Но тогда вам придется пометить каждое свойство, которое вы хотите сериализовать, атрибутами [DataMember]. Лучше указать пустое пространство имен для всех типов в пространстве имен C#, добавив атрибут Assembly в файл Assembly.cs, например:

[assembly: ContractNamespace("", ClrNamespace = "MyServiceModel.DtoTypes")]

Примечание. Вы можете удалить атрибут [Serializable] — он не используется ни одним из сериализаторов ServiceStack. Кроме того, все атрибуты XmlSerializer, такие как [XmlRoot], бесполезны, поскольку ServiceStack использует DataContractSerializer .NET, а не более ранний XmlSerializer от Microsoft.

person mythz    schedule 13.03.2012
comment
Спасибо! Это было недостающее звено, которое мне было нужно! Я почему-то не могу найти подходящую документацию для ServiceStack... - person user1154148; 14.03.2012
comment
По какой причине вы не написали свой собственный десериализатор XML? Кажется, что для Microsoft нужен именно этот тип конфигурации волшебного соуса, чтобы заставить его работать, в отличие от вашего сериализатора/десериализатора JSON, который просто работает. - person JasonD; 02.11.2012
comment
@JasonD Да, мне не нравится NIH без веской причины, и я предпочитаю не использовать XML. MS XML DCS также достаточно эффективна для XML, но при тех усилиях, которые для этого потребовались бы, мало пользы. - person mythz; 02.11.2012