2012-02-07 20 views
5

He escrito un servicio web WCF simple en C# que devuelve registros de una base de datos.Salida XML en el orden incorrecto

El WCF utiliza el siguiente método: getQuestionnaireForID?id=(questionnaireID). El servicio web devuelve todos los registros correctos de la base de datos, sin embargo, parecen estar en el orden incorrecto.

Este es el orden Me gustaría que el XML para estar en:

<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> 

Pero en vez de eso Actualmente retornos en el siguiente orden:

<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> 

No estoy seguro si esto es debido a un documento XML sin estilo o porque tengo mis loops en el orden incorrecto. Aquí está mi descriptor WCF xml.

[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; } 
     } 
    } 

¿Cómo puedo resolver este problema? ¿Causará problemas al tratar de analizar el XML?

+1

Causa problemas al analizar si el analizador está esperando que los elementos estén en orden fijo. –

+1

'¿Cómo puedo resolver este problema?' No puede. ya que no es un problema :) –

+1

@MiserableVariable, ¿qué analizador espera en un orden fijo? Xdocument? XmlDocument? –

Respuesta

5

Este es el orden Me gustaría que el XML para estar en:

¿Por qué? ¿Es esto necesario? Apuesto que casi con seguridad no es necesario.

WCF DataContractSerializer serializa, de forma predeterminada, en orden alfabético. Notará que el XML que está viendo tiene nodos ordenados alfabéticamente. No importa en qué orden enumere sus propiedades de clase.

Puede especificar el orden de los elementos utilizando el atributo Order (consulte MSDN Data Member Order), si es necesario.

La otra opción es usar XMLSerializer, que es más flexible pero no tan simple como el DataContractSerializer.

A menos que exista una genuina que requiera para reordenar estos elementos, entonces no me interesaría.

-1

Se trata de un comportamiento especificado y documentado:

La tabla anterior enumera interfaces de la colección en orden descendente de precedencia. Esto significa, por ejemplo, que si un tipo implementa tanto IList y Generic IEnumerable, la colección es serializado y deserializar según las reglas IList:

En deserialización, todas las colecciones se deserializan por primera creación de una instancia de la escriba llamando al constructor predeterminado, que debe estar presente para que el serializador trate un tipo de colección como durante la serialización y la deserialización.

mirada a la sección "Reglas de recopilación avanzada" de la documentación Collection Types in Data Contracts para todas las normas aplicadas y de las posibles explicaciones de por qué existen.

0

No veo ningún problema con el resultado que está obteniendo.Una de las ventajas de usar XML sobre, por ejemplo, registros de longitud variable o fija es que sus datos contienen suficientes metadatos que permiten que el análisis sea resistente a campos en el orden incorrecto o cualquier otro tipo de estructura. No estoy seguro de si hay analizadores sintácticos que imponen este tipo de comportamiento, pero no deberían. El orden del elemento no es importante en XML.

+0

'El orden de los elementos no es importante en XML' - Esto no es estrictamente cierto. WCF DataContractSerializer exige que el XML esté en un orden específico o, si no, ordenado alfabéticamente. Que es un PITA real –

Cuestiones relacionadas