Не удается получить доступ к элементу после DataContractSerializer - PullRequest
0 голосов
/ 26 декабря 2009

У меня есть простой объект, который я пытаюсь сериализовать с помощью DataContractSerializer.

В моем модульном тесте я пытаюсь убедиться, что xml содержит правильное значение для узла product / sku.

Мой класс продукции:

[DataContract(Namespace = "http://foo.com/catalogue/")
partial class Product
{
   [DataMember(Name = "sku")]
   public virtual string ProductSKU
   {
      get { return _productSKU; }
      set
      {
         OnProductSKUChanging();
        _productSKU = value;
        OnProductSKUChanged();
      }
   }
}

Вот метод, который я тестирую:

public XDocument GetProductXML(Product product)
    {
        var serializer = new DataContractSerializer(typeof(Product));
        var document = new XDocument();

        using (var writer = document.CreateWriter())
        {
            serializer.WriteObject(writer, product);
            writer.Close();
        }

        return document;
    } 

А вот мой юнит-тест:

[Test]
    public void Can_get_product_xml()
    {
        // Arrange
        var product = new Product {Id = 1, Name = "Foo Balls", ProductSKU = "Foo123"};
        var repository = new CatalogueRepository();
        var expectedProductSKU = "Foo123";

        // Act
        var xml = repository.GetProductXML(product);
        var actualProductSKU = xml.Element("product").Element("sku").Value;

        // Assert
        Assert.AreEqual(expectedProductSKU, actualProductSKU);
    }

Проблема в том, что я получаю нулевую ссылку, когда пытаюсь получить доступ к элементам xml, хотя при установке точки останова var xml содержит:

<product xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://foo.com catalogue/">
  <sku>Foo123</sku> 
</product>

Есть идеи, почему это не работает? Нужно ли анализировать сериализованный поток перед добавлением его в XDocument?

1 Ответ

1 голос
/ 26 декабря 2009

Я думаю, что проблема заключается в том факте, что ваш XML-документ имеет пространство имен XML xmlns="http://foo.com catalogue/", но когда вы выбираете с помощью Linq-to-XML, вы никогда не используете это пространство имен каким-либо образом, в той или иной форме.

Кроме того, тег <product> - это ваш корневой тег XML - вы не можете ссылаться на него как на элемент.

Попробуйте что-то вроде этого:

XNamespace ns = "http://foo.com/catalogue/";

var root = xml.Root;
var sku = root.Element(xns + "sku").Value;

Если вы хотите быть уверены, сначала присвойте .Element() переменной и проверьте != null

var sku = root.Element(xns + "sku");
if(sku != null)
{
   var skuValue = first.Value;
}

Надеюсь, это немного поможет!

...