2012-02-07 26 views
5

Tôi đã viết một dịch vụ web WCF đơn giản trong C# để trả về các bản ghi từ cơ sở dữ liệu.Đầu ra XML theo thứ tự sai

WCF sử dụng phương pháp sau: getQuestionnaireForID?id=(questionnaireID). Webservice trả về tất cả các bản ghi chính xác từ cơ sở dữ liệu, tuy nhiên chúng có vẻ sai trật tự.

Đây là thứ tự tôi muốn XML được trong:

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

Nhưng thay vào đó nó hiện lợi nhuận theo thứ tự sau:

<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 không chắc chắn nếu điều này là do đến một tài liệu XML chưa được đặt hoặc vì tôi có các vòng lặp của tôi theo thứ tự sai. Đây là mô tả WCF xml của tôi.

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

Làm cách nào để giải quyết vấn đề này? Nó có gây ra vấn đề khi cố gắng phân tích cú pháp XML không?

+1

Điều này sẽ gây ra sự cố khi phân tích cú pháp nếu trình phân tích cú pháp đang chờ các phần tử theo thứ tự cố định. –

+1

'Làm thế nào tôi có thể giải quyết vấn đề này? 'Bạn không thể. vì đó không phải là vấn đề :) –

+1

@MiserableVariable, trình phân tích cú pháp nào mong đợi theo một thứ tự cố định? Xdocument? XmlDocument? –

Trả lời

5

Đây là thứ tự tôi muốn XML được trong:

Tại sao? Điều này có cần thiết không? Tôi cược nó gần như chắc chắn không cần thiết.

WCF DataContractSerializer serializes - theo mặc định - theo thứ tự bảng chữ cái. Bạn sẽ lưu ý rằng XML bạn đang thấy có các nút được sắp xếp theo thứ tự bảng chữ cái. Nó không quan trọng thứ tự bạn liệt kê thuộc tính lớp học của bạn.

Bạn có thể chỉ định thứ tự các phần tử sử dụng thuộc tính Order (xem MSDN Data Member Order), nếu cần.

Tùy chọn khác là sử dụng XMLSerializer, linh hoạt hơn nhưng không đơn giản như DataContractSerializer.

Trừ khi có chính hãng cần để sắp xếp lại các yếu tố này thì tôi sẽ không quan tâm đến bản thân.

-1

Đây là một hành vi quy định và tài liệu:

Các bảng trước liệt kê các giao diện bộ sưu tập thứ tự giảm dần của được ưu tiên. Điều này có nghĩa, ví dụ, rằng nếu một loại thực hiện cả hai IList và Generic IEnumerable, bộ sưu tập là tuần tự và deserialized theo các quy tắc IList:

Tại deserialization, tất cả các bộ sưu tập được deserialized bằng cách đầu tiên tạo một thể hiện của gõ bằng cách gọi hàm khởi tạo mặc định, phải có để trình nối tiếp xử lý loại bộ sưu tập dưới dạng bộ sưu tập trong cả hai lần tuần tự hóa và deserialization.

Xem phần "Quy tắc thu thập nâng cao" của tài liệu Collection Types in Data Contracts cho tất cả các quy tắc được áp dụng và để có thể giải thích tại sao chúng tồn tại.

0

Tôi không thấy bất kỳ vấn đề nào với kết quả bạn nhận được.Một trong những lợi thế của việc sử dụng XML trên, nói, các bản ghi độ dài cố định hoặc cố định là dữ liệu của bạn chứa đủ siêu dữ liệu cho phép phân tích cú pháp có khả năng chống các trường theo thứ tự sai hoặc bất kỳ loại cấu trúc nào khác. Tôi không chắc liệu có những trình phân tích cú pháp ra khỏi đó để thực thi loại hành vi này, nhưng chúng không nên. Thứ tự phần tử không quan trọng trong XML.

+0

'Thứ tự phần tử không quan trọng trong XML' - Điều này không đúng. WCF DataContractSerializer yêu cầu XML theo thứ tự được chỉ định, hoặc nếu không theo thứ tự bảng chữ cái. Đó là một PITA thực sự. –

Các vấn đề liên quan