Десериализация XML работает только с пространством имен в XML - PullRequest
8 голосов
/ 13 марта 2012

Самый простой способ заставить десериализацию xml ServiceStack работать, когда 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.

1 Ответ

24 голосов
/ 14 марта 2012

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

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

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

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

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

...