简体   繁体   中英

XML Output In the Wrong Order

I have written a simple WCF web service in C# which returns records from a database.

The WCF uses the following method: getQuestionnaireForID?id=(questionnaireID) . The Webservice returns all the correct records from the database, however they appear to be in the wrong order.

This is the order I would like the XML to be in:

<QuestionnaireXML xmlns="http://schemas.datacontract.org/2004/07/QuestionnaireDescriptor" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
    <QuestionnaireName>Sample Questionnaire</QuestionnaireName>
        <Questions>
            <Question>
                <QuestionID>297</QuestionID>
                <QuestionName>What is your favorite type of tree?</QuestionName>
                <Answers>
                    <Answer>
                        <AnswerTitle>Beech</AnswerTitle>
                    </Answer>
                    <Answer>
                        <AnswerTitle>Oak</AnswerTitle>
                    </Answer>
                </Answers>
            </Question>
            <Question>
                <QuestionID>298</QuestionID>
                <QuestionName>Windows or Mac?</QuestionName>
                <Answers>
                    <Answer>
                        <AnswerTitle>Mac</AnswerTitle>
                    </Answer>
                    <Answer>
                        <AnswerTitle>Windows</AnswerTitle>
                    </Answer>
                </Answers>
            </Question>
        </Questions>
</QuestionnaireXML>

But instead it currently returns in the following order:

<QuestionnaireXML xmlns="http://schemas.datacontract.org/2004/07/QuestionnaireDescriptor" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
    <QuestionnaireName>Hello sir how do you do today?</QuestionnaireName>
    <Questions>
        <Question>
            <Answers>
                <Answer>
                    <AnswerTitle>Beech</AnswerTitle>
                </Answer>
                <Answer>
                    <AnswerTitle>Oak</AnswerTitle>
                </Answer>
            </Answers>
            <QuestionID>297</QuestionID>
            <QuestionName>What is your favorite type of tree?</QuestionName>
        </Question>
        <Question>
            <Answers>
                <Answer>
                    <AnswerTitle>Mac</AnswerTitle>
                </Answer>
                <Answer>
                    <AnswerTitle>Windows</AnswerTitle>
                </Answer>
            </Answers>
            <QuestionID>298</QuestionID>
            <QuestionName>Windows or Mac?</QuestionName>
        </Question>
    </Questions>
</QuestionnaireXML>

Im not sure if this is due to an unstyled XML document or because I have my loops in the wrong order. Here is my WCF xml descriptor.

[DataContract]
    public class QuestionnaireXML
    {
        OsqarSQL getData;
        DataTable DT;
        private String _questionnaireName;
        private List<Question> _Question = new List<Question>();

        public QuestionnaireXML(int QuestionnaireID)
        {
            // Loop through datatable for questionIDs and load the questions
            getData = new OsqarSQL();
            _questionnaireName = getData.GetQuestionnaireName(QuestionnaireID);
            DT = getData.GetQuestionIDWCF(QuestionnaireID);
            for (int i = 0; i < DT.Rows.Count; i++)
            {
                _Question.Add(new Question(Int32.Parse(DT.Rows[i][0].ToString())));
            }
        }

        // Define DataMembers for XML output
        [DataMember]
        public String QuestionnaireName
        {
            get { return _questionnaireName; }
            set { _questionnaireName = value; }
        }

        [DataMember]
        public List<Question> Questions
        {
            get { return _Question; }
            set { _Question = value; }
        }
    }

    [DataContract]
    public class Question
    {
        private Int32 _questionId;
        private String _questionName;
        OsqarSQL getData;
        DataTable DT;
        DataTable AT;
        private List<Answer> _Answer = new List<Answer>();

        public Question(int QuestionID)
        {
            getData = new OsqarSQL();
            DT = getData.GetQuestionNameWCF(QuestionID);
            _questionId = (int)DT.Rows[0][0];
            _questionName = DT.Rows[0][1].ToString();
            AT = getData.GetAnswerTitle(QuestionID);
            for (int i = 0; i < AT.Rows.Count; i++)
            {
                _Answer.Add(new Answer(Int32.Parse(AT.Rows[i][0].ToString())));
            }
        }

        // Define DataMembers for XML output
        [DataMember]
        public Int32 QuestionID
        {
            get { return _questionId; }
            set { _questionId = value; }
        }

        [DataMember]
        public String QuestionName
        {
            get { return _questionName; }
            set { _questionName = value; }
        }

        [DataMember]
        public List<Answer> Answers
        {
            get { return _Answer; }
            set { _Answer = value; }
        }
    }

    [DataContract]
    public class Answer
    {
        private Int32 _answerId;
        private String _answerTitle;
        OsqarSQL getData;
        DataTable DT;

        // Constructor Logic
        public Answer(int AnswerID)
        {
            getData = new OsqarSQL();
            DT = getData.GetAnswerTitleWcf(AnswerID);
            _answerTitle = DT.Rows[0][1].ToString();   
        }

        // Define DataMembers for XML output
        [DataMember]
        public String AnswerTitle
        {
            get { return _answerTitle; }
            set { _answerTitle = value; }
        }
    }

How can I resolve this problem? Will it cause issues when trying to parse the XML?

This is the order I would like the XML to be in:

Why? Is this necessary? I'd wager it's almost certainly not necessary.

The WCF DataContractSerializer serializes - by default - in alphabetical order. You'll note that the XML you are seeing has nodes ordered alphabetically. It does not matter which order you list your class properties.

You can specify the order of elements using the Order attribute (see MSDN Data Member Order ), if necessary.

The other option is to use the XMLSerializer, which is more flexible but not as simple as the DataContractSerializer.

Unless there is a genuine need to re-order these elements then I would not concern myself with it.

I don't see any problems with the result you're getting. One of the advantages of using XML over, say, variable or fixed length records is that your data contains enough metadata that enables parsing to be resistant to fields in the wrong order or any other types of structure. I'm not sure if there are parsers out there that enforces this kind of behavior, but they shouldn't. Element order isn't important in XML.

This is a specified and documented behaviour:

The preceding table lists collection interfaces in descending order of precedence. This means, for example, that if a type implements both IList and Generic IEnumerable, the collection is serialized and deserialized according to the IList rules:

At deserialization, all collections are deserialized by first creating an instance of the type by calling the default constructor, which must be present for the serializer to treat a collection type as a collection during both serialization and deserialization.

Look at "Advanced Collection Rules" section of the Collection Types in Data Contracts documentation for all the rules applied and for possible explanations of WHY they exist.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM