2013-09-04 2 views
1

Я использую XmlSerializer для создания документа xml, используемого для больших коммерческих сервисов ebay.C# XmlSerializer xmlns в дочернем элементе, соответствующем родительскому

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<BulkDataExchangeRequests xmlns="urn:ebay:apis:eBLBaseComponents"> 
    <Header> 
     <SiteID>0</SiteID> 
     <Version>775</Version> 
    </Header> 
    <AddFixedPriceItemRequest xmlns="urn:ebay:apis:eBLBaseComponents"> 
<Version>775</Version> 

<Item> 
    <AutoPay>false</AutoPay> 
    <BuyerProtection>ItemIneligible</BuyerProtection> 
    <BuyItNowPrice currencyID="USD">0.0</BuyItNowPrice> 
    <Country>US</Country> 
    <Currency>USD</Currency> 
    <Description>test</Description> 
    <GiftIcon>0</GiftIcon> 
</Item> 
</AddFixedPriceItemRequest> 
</BulkDataExchangeRequests> 

Проблема у меня является получение AddFixedPriceItemRequest порожденного сериализатором на самом деле содержит, что XMLNS как BulkDataExchangeRequests элемента имеет. Кажется, это требование, чтобы это работало. Я генерировать насыпной тег с помощью:

writer.WriteStartElement("BulkDataExchangeRequests", "urn:ebay:apis:eBLBaseComponents"); 

я создаю сериалайзер.

serializer = new XmlSerializer(typeof(AddFixedPriceItemRequestType));//, "urn:ebay:apis:eBLBaseComponents"); 

и сериализации с пространством имен

request = new AddFixedPriceItemRequestType() 
{ 
//populate data. 
}; 

XmlSerializerNamespaces namespaces = new XmlSerializerNamespaces(); 
namespaces.Add("", "urn:ebay:apis:eBLBaseComponents"); 

serializer.Serialize(writer, request, namespaces); 

Это тип с XML-атрибуты:

[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "2.0.50727.5420")] 
[System.SerializableAttribute()] 
[System.Diagnostics.DebuggerStepThroughAttribute()] 
[System.ComponentModel.DesignerCategoryAttribute("code")] 
[System.Xml.Serialization.XmlTypeAttribute(Namespace="urn:ebay:apis:eBLBaseComponents",TypeName="AddFixedPriceItemRequest")] 
public partial class AddFixedPriceItemRequestType : AbstractRequestType { 
//filled in class 
} 

мой выход заканчивается так:

<AddFixedPriceItemRequest xmlns=""> 
    <ErrorLanguage xmlns="urn:ebay:apis:eBLBaseComponents">en_US</ErrorLanguage> 
    <Version xmlns="urn:ebay:apis:eBLBaseComponents">837</Version> 
    <Item p4:type="Item" xmlns:p4="http://www.w3.org/2001/XMLSchema-instance" xmlns="urn:ebay:apis:eBLBaseComponents"> 

Могли кто-то помогает в том, как xmlns из addfixedpriceitemrequest устанавливается в соответствии с массивными xmlns через сериализатор. Или порекомендуйте другой способ сделать это. Я пытался избежать записи каждого свойства с помощью createelement/writeelement.

+0

Вы уверены, что это переопределить из милиции 'xmlns' на' AddFixedPriceItemRequest' уровне? Он уже определен в 'BulkDataExchangeRequests' и должен быть унаследован должным образом. Но itdefinitely * не следует * переопределять как 'xmlns =" ​​"' – DarkWalker

ответ

0

Проблема, скорее всего, заключается в XmlTypeAttribute - кажется, вы используете свой класс в качестве контейнера верхнего уровня - вы должны использовать XmlRootAttribute insted. Таким образом, вы получите urn:ebay:apis:eBLBaseComponents в правильном месте.

Пример:

void Main() 
{ 
    var t = new A {FieldOfB = new B {C = 5}}; 

    var serializer = new XmlSerializer(typeof(A)); 


    using (var writer = new StringWriter()) 
    { 
     serializer.Serialize(writer, t); 
     writer.ToString().Dump(); 
    } 
} 

При использовании этого определения класса:

[System.Xml.Serialization.XmlTypeAttribute(Namespace="urn:ebay:apis:eBLBaseComponents")] 
public class A 
{ 
    public B FieldOfB {get;set;} 
} 

public class B 
{ 
    public int C {get;set;} 
} 

дает этот результат:

<?xml version="1.0" encoding="utf-16"?> 
<A xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <FieldOfB xmlns="urn:ebay:apis:eBLBaseComponents"> 
    <C>5</C> 
    </FieldOfB> 
</A> 

И если вы исправить атрибут:

[System.Xml.Serialization.XmlRootAttribute(Namespace="urn:ebay:apis:eBLBaseComponents")] 
public class A 
{ 
    public B FieldOfB {get;set;} 
} 

public class B 
{ 
    public int C {get;set;} 
} 

Вы получаете это:

<?xml version="1.0" encoding="utf-16"?> 
<A xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="urn:ebay:apis:eBLBaseComponents"> 
    <FieldOfB> 
    <C>5</C> 
    </FieldOfB> 
</A> 
1

Это работает для меня


ItemType itemType = new ItemType() 
{ 
    //populate data. 
}; 
ApiCall apiCall = new AddItemCall() { Item = itemType }; 
AddItemRequestType addFixedPriceItemRequestType = ((AddItemCall)apiCall).ApiRequest; 
XmlSerializerNamespaces namespaces = new XmlSerializerNamespaces(new XmlQualifiedName[] { 
    new XmlQualifiedName(string.Empty, "urn:ebay:apis:eBLBaseComponents")}); 
XmlSerializer xmlSerializer = new XmlSerializer(
    addFixedPriceItemRequestType.GetType(), "urn:ebay:apis:eBLBaseComponents"); 
MemoryStream memoryStream = new MemoryStream(); 
xmlSerializer.Serialize(memoryStream, addFixedPriceItemRequestType , namespaces); 
memoryStream.Seek((long)0, SeekOrigin.Begin); 
XmlDocument xmlDocument = new XmlDocument(); 
xmlDocument.Load(memoryStream); 
memoryStream.Close(); 
string addItemRequestTypeXML = xmlDocument.OuterXml; 

Выход собирается быть:


<AddItemRequestType xmlns="urn:ebay:apis:eBLBaseComponents"> 
    <Item> 
    <ApplicationData></ApplicationData> 
    <AutoPay>false</AutoPay> 
    <CategoryMappingAllowed>true</CategoryMappingAllowed> 
    <Country>US</Country> 
    <Currency>EUR</Currency> 
    <Description> 
    .... 

<AddItemRequestType> 
0

eBay требует установки пространства имен только в Trade API. Одним из решений является удаление установки пространства имен в объектах BulkDataExchange и добавление параметров пространства имен только в объект Trade API. Это не стандартный формат XML, однако eBay только принимает это.

В вашем случае, это может сделать трюк на eBay:

writer.WriteStartElement("BulkDataExchangeRequests", ""); 
Смежные вопросы