none
Attributes via XElement in C#_List of objects RRS feed

  • Question

  • I have a class "WsReferenceValue" that contains a list of other class "Characteristic" ,and the class Characteristic has a property another class "Definition",this is my code:

    public class WsReferenceValue
     {
         [DataContract]
    public class WsReferenceValue : WsEntitiesDimension
    {
        public List<Characteristic> listCharacteristic { get; set; }       
    }
         [DataContract]
    public class Characteristic
    {      
         [DataMember]      
        public Definition definition { get; set; } 
    }
    
       [Serializable]   
    public class Definition
    {
          [XmlAttribute]
        public int id;
          [XmlAttribute]
        public string name;
    }

    *** My code :

    WsReferenceValue referenceV = new WsReferenceValue();
     List<Characteristic> ListFinalDynamic = new List<Characteristic>();
     foreach (var finalCharac in listeCharactresticFinal)
     {
                    var lstChars = new Characteristic()
                            {
                                Definition = new Definition()
                                {
                                    id = Dimension.ID,
                                    name = Dimension.Name
                                }
                            };                          
                 ListFinalDynamic.Add(lstChars);                    
                referenceV.listCharacteristic = ListFinalDynamic;    
    }

    And I get this result:

    <WsReferenceValue>                     
     <listCharacteristic>
                    <Characteristic>
                        <Definition>
                            <id>1</id>
                            <name>COMPANY</name>
                        </Definition>
                    </Characteristic>
    
                    <Characteristic>
                        <Definition>
                            <id>71</id>
                            <name>COUNTRY</name>
                        </Definition>
                    </Characteristic>
    
                    <Characteristic>
                        <Definition>
                            <id>45</id>
                            <name>CURRENCY</name>
                        </Definition>
                    </Characteristic>
      </listCharacteristic>

    And my goal is to get all list of Characterstics for one Reference with this format : (every Characterstic with attributes)

    <WsReferenceValue>                     
     <listCharacteristic>
                    <Characteristic>
                        <Definition id=1 name="COMPANY" />                        
                    </Characteristic>
    
                    <Characteristic>
                        <Definition id=71 name="COUNTRY" />
                    </Characteristic>
    
                    <Characteristic>
                        <Definition id=45 name="CURRENCY" />                      
                    </Characteristic>
      </listCharacteristic>

    How can I fix it ? Thanks

    Wednesday, November 13, 2019 1:51 PM

All replies

  • You didn't specify how you're serializing the data. Since you put DataContract we could assume that you're using DataContractSerializer but some of your properties aren't marked as data members. This serializer does not support attributes. In general that should be fine as it is a data contract, the format shouldn't matter.

    However if you really want to use attributes you can use XmlSerializer instead.


    Michael Taylor http://www.michaeltaylorp3.net

    Wednesday, November 13, 2019 3:03 PM
    Moderator
  • Thanks @CoolDadTx for your reply,

    Sorry I am not well understand "how you're serializing the data ", I do all the work and at end I add the result to my instance and I return this result, and this is result screenshot from POSTMAN

    For the some properties aren't marked as data members because I want to make ID and NAME as XATTRIBUTES, if there is other method or any advise .

    I am sorry for my confused, because really it is 
    vague for me.

    Any help or guiding for me to correct it or modify the necessary to get the goal.
    Thanks a lot,

    Wednesday, November 13, 2019 3:35 PM
  • Right, you're calling an .svc endpoint which means this is a WCF service. Hence you're using DataContract. You cannot use attributes with DataContract serializer. Since you are likely just returning your business object and the WCF runtime is serializing the results for you then you cannot change that. 

    This is a service interface so you should be using elements anyway. However if you really, really want to use attributes then you must use the XmlSerializer. That is not the default for WCF. Here's an article on how to do that. Basically (never done this myself) it looks like you just need to attribute your WCF service.


    Michael Taylor http://www.michaeltaylorp3.net

    Wednesday, November 13, 2019 4:05 PM
    Moderator
  • Thanks a lot ! I am understand very well ,really very thanks.

    I could not use XmlSerializer for the performance and I have other class using DataContract.

    I try this code:

    public class WsReferenceValue
     {
         [DataContract]
    public class WsReferenceValue : WsEntitiesDimension
    {
        public List<Characteristic> listCharacteristic { get; set; }       
    }
         [DataContract]
    public class Characteristic
    {      
         [DataMember]      
        public XElement Definition { get; set; } 
    }

    And I get this result ,it is nearly my objectif:

     <listCharacteristic>
          <Characteristic>
              <Definition>
                    <Definition ID="1" NAME="COMPANY" xmlns=""/> 
              </Definition>
         </Characteristic>
         <Characteristic>
              <Definition>
                  <Definition ID="71" NAME="COUNTRY" xmlns=""/> 
              </Definition>
          /Characteristic>

    Just I get  duplicate the "<Definition>",I want:

    <Characteristic>   
                <Definition ID="1" NAME="COMPANY" xmlns=""/>
    </Characteristic>

    If you can help me for this ?

    Anyway, I get nearly my goal and I understand very well the problem,

    thank you very much

    Wednesday, November 13, 2019 4:29 PM
  • I personally would recommend against this. DataContract is for business contracts. Anything that you put in there should be consumable in business code. Many languages have toolsets that can auto-generate client code to support the contract so letting a persistence type like XElement into the data contract is just making it hard for everybody. Unless you have a pre-defined schema that you must exactly match (in which case you should be using XML) then the raw XML isn't relevant to anybody so why make the data contract suffer?

    I'm thinking about how the client/server would need to generate this data just to meet your XML requirements.

    var data = new WsReferenceValue()
    {
        listCharacteristic = new List<Characteristic>()
        {
            new Characteristic() {
                Definition = new XElement("Definition", new XAttribute("ID", 1), new XAttribute("NAME", "COMPANY"))
            },
            new Characteristic() {
                Definition = new XElement("Definition", new XAttribute("ID", 1), new XAttribute("NAME", "COMPANY"))
            }
        }
    };

    That goes completely against the purpose of data contracts.

    As for your data it appears it just a data creation problem on your part. You have duplicate items in your data object you're serializing. The above object when I serialize it produces this.

    <?xml version="1.0" encoding="utf-16"?>
    <WsReferenceValue xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/ConsoleApp1">
      <listCharacteristic>
        <Characteristic>
          <Definition>
            <Definition ID="1" NAME="COMPANY" xmlns="" />
          </Definition>
        </Characteristic>
        <Characteristic>
          <Definition>
            <Definition ID="2" NAME="COMPANY2" xmlns="" />
          </Definition>
        </Characteristic>
      </listCharacteristic>
    </WsReferenceValue>

    With this code.

    var serializer = new DataContractSerializer(typeof(WsReferenceValue));
    
    var builder = new StringBuilder();
    using (var writer = XmlWriter.Create(builder, new XmlWriterSettings() { Indent = true }))
    {
        serializer.WriteObject(writer, data);
    };
    
    var str = builder.ToString();
    Console.WriteLine(str);


    Michael Taylor http://www.michaeltaylorp3.net

    Wednesday, November 13, 2019 6:49 PM
    Moderator