Development Tip

ASP.NET에서 XML을 반환하는 방법은 무엇입니까?

yourdevel 2020. 12. 25. 10:32
반응형

ASP.NET에서 XML을 반환하는 방법은 무엇입니까?


ASP.NET에서 XML을 반환하는 작업에 대한 많은 반쪽 솔루션을 만났습니다. 하지만 대부분의 경우 작동하는 코드를 맹목적으로 복사하여 붙여넣고 싶지는 않습니다. 나는 올바른 코드를 원하고 그것이 옳은 이유 를 알고 싶습니다 . 나는 비판을 원한다. 나는 정보를 원한다. 나는 지식을 원한다. 이해를 원합니다.

다음은 복잡성이 증가하는 순서대로 코드 조각으로, 각 항목이 야기하는 추가 질문 중 일부를 포함하여 제가 본 부분적인 솔루션 중 일부를 나타냅니다. 여기에 답변하고 싶습니다.

철저한 답변은 왜 우리 다음 사항을 가져야 하는지 또는 가져야 하는지에 대해 설명 해야하며 그렇지 않은 경우 왜 관련성이 없는지 설명해야합니다.

  • Response.Clear ();
  • Response.ContentType = "텍스트 / xml";
  • Response.ContentEncoding = Encoding.UTF8;
  • Response.ContentEncoding = Encoding.UTF16;
  • Response.ContentType = "text / xml; charset = utf-8";
  • Response.ContentType = "text / xml; charset = utf-16";
  • Response.End ()
  • 프론트 파일 용기가 찢어진 aspx 사용
  • ashx 파일 사용

결국 다음과 같이 도우미 함수의 내용을 작성해야한다고 상상해보십시오.

///<summary>Use this call inside your (Page_Xxx) method to write the
///xml to the web client. </summary>
///<remarks>See for https://stackoverflow.com/questions/543319/how-to-return-xml-in-asp-net
///for proper usage.</remarks>
public static void ReturnXmlDocumentToWebClient(
    XmlDocument document,
    Page page)
{
   ...
}

내가 보는 모든 솔루션은 빈 aspx 페이지를 가져오고 전면 파일에서 모든 HTML을 자르는 것으로 시작합니다 (Visual Studio에서 경고가 발생 함).

<%@ Page Language="C#"
      AutoEventWireup="true"
      CodeFile="GetTheXml.aspx.cs"
      Inherits="GetTheXml" %>

다음으로 Page_Load이벤트를 사용 하여 출력에 씁니다.

protected void Page_Load(object sender, EventArgs e)
{
   String xml = "<foo>Hello, world!</foo>";

   Response.Write(xml);
}

ContentType"text / xml" 로 변경해야 합니까? 즉 :

protected void Page_Load(object sender, EventArgs e)
{
   String xml = "<foo>Hello, world!</foo>";

   Response.ContentType = "text/xml";
   Response.Write(xml);
}

Response.Clear먼저 전화해야 하나요?

protected void Page_Load(object sender, EventArgs e)
{
   String xml = "<foo>Hello, world!</foo>";

   Response.Clear();
   Response.ContentType = "text/xml";
   Response.Write(xml);
}

정말 그렇게 불러야하나요? Response.Clear앞 파일의 코드가 <% ... %>불필요한 것 외에 비어 있는지 (공백이나 캐리지 리턴도 아님) 확인하는 이전 단계를 수행 하지 않습니까?

합니까는 Response.Clear누군가가 코드 앞에 파일에 빈 줄이나 공간으로 남게 경우, 더 강력하게?

ashx를 빈 aspx 주 파일과 동일하게 사용하고 있습니까? HTML을 출력하지 않을 것임을 이해하기 때문입니까?


전화해야 Response.End하나요? 즉 :

protected void Page_Load(object sender, EventArgs e)
{
   String xml = "<foo>Hello, world!</foo>";

   Response.Clear();
   Response.ContentType = "text/xml";
   Response.Write(xml);
   Response.End();
}

그 이후 Response.Write당장 응답을 종료해야하는 다른 일이 발생할 수 있습니까?


컨텐츠 유형이 text/xml충분하거나 대신 text / xml 이어야합니다 . charset = utf-8 ?

protected void Page_Load(object sender, EventArgs e)
{
   String xml = "<foo>Hello, world!</foo>";

   Response.Clear();
   Response.ContentType = "text/xml; charset=utf-8";
   Response.Write(xml);
   Response.End();
}

아니면 구체적으로 그렇지 않습니까? 콘텐츠 유형에 문자 집합이 있지만 속성을 설정하지 않으면 서버가 망가 듭니까?

다른 콘텐츠 유형이 아닌 이유는 무엇입니까?

  • UTF-8
  • utf-16
  • UTF-16

문자 집합을 지정해야합니까 Response.ContentEncoding?

protected void Page_Load(object sender, EventArgs e)
{
   String xml = "<foo>Hello, world!</foo>";

   Response.Clear();
   Response.ContentType = "text/xml";
   Response.ContentEncoding = Encoding.UTF8;
   Response.Write(xml);
   Response.End();
}

Response.ContentEncoding잼보다 사용하는 것이 더 낫 Response.ContentType습니까? 더 나쁜가요? 전자가 지원됩니까? 후자입니까?


실제로 String을 작성하고 싶지 않습니다. 나는 XmlDocument. 누군가 내가 다음을 사용할 수 있다고 제안합니다XmlWriter .

protected void Page_Load(object sender, EventArgs e)
{
   XmlDocument xml = GetXmlDocumentToShowTheUser();

   Response.Clear();
   Response.ContentType = "text/xml";
   Response.ContentEncoding = Encoding.UTF8;

   using (TextWriter textWriter = new StreamWriter(
         Response.OutputStream,
         Encoding.UTF8))
   {
       XmlTextWriter xmlWriter = new XmlTextWriter(textWriter);
       // Write XML using xmlWriter
       //TODO: How to do this?
   }
}

Response.OutputStream대신을 사용하십시오 Response.Write. 좋은가요? 나쁜? 보다 나은? 보다 나쁜? 더 빨리? 천천히? 더 많은 메모리 집약적? 메모리 사용량이 적습니까?


나는 당신이 렌더링해야한다고 읽었습니다.

Page_Load ()를 사용할 때 발생하는 청킹 문제를 방지하기 위해 페이지의 Render () 메서드에 XML을 추가합니다.

청킹 이란 무엇입니까 ? 청킹의 문제점은 무엇이며 using을 사용 Page_Render하면 어떻게 제거됩니까?


XmlDocument개체 의 내용을 문자열에 쓰고 메모리를 낭비하기 때문에 쓰고 싶지 않습니다 . 즉, 다음 중 하나라도 나쁠 것입니다.

Response.Write(doc.ToString());
Response.Write(doc.InnerXml);
xmlWrite.WriteString(doc.ToString());
xmlWrite.WriteString(doc.InnerXml);

유제

ASP.NET에서 XML을 반환하는 방법

참고 문헌

ASP.NET 1.1에서 ASPX에서 XML을 반환하는 방법

ASP.NET 웹 페이지에 XML 출력 쓰기

ASP.NET에서 XML을 어떻게 출력합니까?

ASP.NET에서 ASHX 처리기 만들기


ASP.NET의 클라이언트에 XML을 반환하는 적절한 방법을 찾았습니다. 잘못된 길을 지적하면 옳은 길을 더 이해할 수있을 것 같아요.

틀림 :

Response.Write(doc.ToString());

틀림 :

Response.Write(doc.InnerXml);

틀림 :

Response.ContentType = "text/xml";
Response.ContentEncoding = System.Text.Encoding.UTF8;
doc.Save(Response.OutputStream);

옳은:

Response.ContentType = "text/xml"; //Must be 'text/xml'
Response.ContentEncoding = System.Text.Encoding.UTF8; //We'd like UTF-8
doc.Save(Response.Output); //Save to the text-writer
      //using the encoding of the text-writer
      //(which comes from response.contentEncoding)

TextWriter 사용

마십시오 하지 사용Response.OutputStream

음주 사용Response.Output

모두 스트림하지만 OutputA는 TextWriter를 . 에서 XmlDocument자신을 TextWriter에 저장할해당 TextWriter에서 지정한 인코딩 을 사용합니다 . XmlDocument는 TextWriter에서 사용하는 인코딩과 일치하도록 xml 선언 노드를 자동으로 변경합니다. 예를 들어이 경우 XML 선언 노드 :

<?xml version="1.0" encoding="ISO-8859-1"?>

될 것이다

<?xml version="1.0" encoding="UTF-8"?>

이는 TextWriter가 UTF-8로 설정 되었기 때문입니다. (자세한 내용은 잠시 후). TextWriter에 문자 데이터가 제공되면 설정된 인코딩에 적합한 바이트 시퀀스로 인코딩됩니다.

틀림 :

doc.Save(Response.OutputStream);

이 예에서 문서는 인코딩 변경을 수행하지 않는 OutputStream에 잘못 저장되었으며 응답의 콘텐츠 인코딩 또는 XML 선언 노드의 지정된 인코딩과 일치하지 않을 수 있습니다.

옳은

doc.Save(Response.Output);

XML 문서가 TextWriter 개체에 올바르게 저장되어 인코딩이 올바르게 처리됩니다.


인코딩 설정

헤더에서 클라이언트에게 제공되는 인코딩 :

Response.ContentEncoding = ...

XML 문서의 인코딩과 일치해야합니다.

<?xml version="1.0" encoding="..."?>

클라이언트에 전송 된 바이트 시퀀스에있는 실제 인코딩과 일치해야합니다. 이 세 가지가 모두 일치하도록하려면 단일 행을 설정하십시오.

Response.ContentEncoding = System.Text.Encoding.UTF8;

Response 객체 에 인코딩이 설정 되면 TextWriter 에 동일한 인코딩이 설정 됩니다. TextWriter의 인코딩 집합은 XmlDocumentxml 선언 을 변경하도록합니다 .

<?xml version="1.0" encoding="UTF-8"?>

문서가 저장 될 때 :

doc.Save(someTextWriter);

응답 출력에 저장

문서를 바이너리 스트림에 저장하거나 문자열을 작성하지 않으려 고합니다.

틀림 :

doc.Save(Response.OutputStream);

여기서 XML은 이진 스트림에 잘못 저장됩니다. 최종 바이트 인코딩 시퀀스는 XML 선언 또는 웹 서버 응답의 콘텐츠 인코딩과 일치하지 않습니다.

틀림 :

Response.Write(doc.ToString());
Response.Write(doc.InnerXml);

여기서 XML은 인코딩이없는 문자열로 잘못 변환됩니다. XML 선언 노드가 응답의 인코딩을 반영하도록 업데이트되지 않았고 응답이 응답의 인코딩과 일치하도록 올바르게 인코딩되지 않았습니다. 또한 XML을 중간 문자열에 저장하면 메모리가 낭비됩니다.

당신은 하지 않는 문자열로 XML을 저장하려는, 또는 문자열로 XML 물건 response.Write이 있기 때문에, 문자열을 :

- doesn't follow the encoding specified
- doesn't set the XML declaration node to match
- wastes memory

음주 사용doc.Save(Response.Output);

마십시오 하지 사용doc.Save(Response.OutputStream);

마십시오 하지 사용Response.Write(doc.ToString());

마십시오 하지 사용 '을 Response.Write (doc.InnerXml);'


콘텐츠 유형 설정

응답의 ContentType은로 설정되어야합니다 "text/xml". 그렇지 않은 경우 클라이언트는 XML을 보내는 것을 알지 못합니다.

최종 답변

Response.Clear(); //Optional: if we've sent anything before
Response.ContentType = "text/xml"; //Must be 'text/xml'
Response.ContentEncoding = System.Text.Encoding.UTF8; //We'd like UTF-8
doc.Save(Response.Output); //Save to the text-writer
    //using the encoding of the text-writer
    //(which comes from response.contentEncoding)
Response.End(); //Optional: will end processing

완전한 예

Rob Kennedy는 처음부터 끝까지의 예를 포함하지 못했다는 점을 잘 지적했습니다.

GetPatronInformation.ashx :

<%@ WebHandler Language="C#" Class="Handler" %>

using System;
using System.Web;
using System.Xml;
using System.IO;
using System.Data.Common;

//Why a "Handler" and not a full ASP.NET form?
//Because many people online critisized my original solution
//that involved the aspx (and cutting out all the HTML in the front file),
//noting the overhead of a full viewstate build-up/tear-down and processing,
//when it's not a web-form at all. (It's a pure processing.)

public class Handler : IHttpHandler
{
   public void ProcessRequest(HttpContext context)
   {
      //GetXmlToShow will look for parameters from the context
      XmlDocument doc = GetXmlToShow(context);

      //Don't forget to set a valid xml type.
      //If you leave the default "text/html", the browser will refuse to display it correctly
      context.Response.ContentType = "text/xml";

      //We'd like UTF-8.
      context.Response.ContentEncoding = System.Text.Encoding.UTF8;
      //context.Response.ContentEncoding = System.Text.Encoding.UnicodeEncoding; //But no reason you couldn't use UTF-16:
      //context.Response.ContentEncoding = System.Text.Encoding.UTF32; //Or UTF-32
      //context.Response.ContentEncoding = new System.Text.Encoding(500); //Or EBCDIC (500 is the code page for IBM EBCDIC International)
      //context.Response.ContentEncoding = System.Text.Encoding.ASCII; //Or ASCII
      //context.Response.ContentEncoding = new System.Text.Encoding(28591); //Or ISO8859-1
      //context.Response.ContentEncoding = new System.Text.Encoding(1252); //Or Windows-1252 (a version of ISO8859-1, but with 18 useful characters where they were empty spaces)

      //Tell the client don't cache it (it's too volatile)
      //Commenting out NoCache allows the browser to cache the results (so they can view the XML source)
      //But leaves the possiblity that the browser might not request a fresh copy
      //context.Response.Cache.SetCacheability(HttpCacheability.NoCache);

      //And now we tell the browser that it expires immediately, and the cached copy you have should be refreshed
      context.Response.Expires = -1;

      context.Response.Cache.SetAllowResponseInBrowserHistory(true); //"works around an Internet&nbsp;Explorer bug"

      doc.Save(context.Response.Output); //doc saves itself to the textwriter, using the encoding of the text-writer (which comes from response.contentEncoding)

      #region Notes
      /*
       * 1. Use Response.Output, and NOT Response.OutputStream.
       *  Both are streams, but Output is a TextWriter.
       *  When an XmlDocument saves itself to a TextWriter, it will use the encoding
       *  specified by the TextWriter. The XmlDocument will automatically change any
       *  XML declaration node, i.e.:
       *     <?xml version="1.0" encoding="ISO-8859-1"?>
       *  to match the encoding used by the Response.Output's encoding setting
       * 2. The Response.Output TextWriter's encoding settings comes from the
       *  Response.ContentEncoding value.
       * 3. Use doc.Save, not Response.Write(doc.ToString()) or Response.Write(doc.InnerXml)
       * 3. You DON'T want to save the XML to a string, or stuff the XML into a string
       *  and response.Write that, because that
       *   - doesn't follow the encoding specified
       *   - wastes memory
       *
       * To sum up: by Saving to a TextWriter: the XML Declaration node, the XML contents,
       * and the HTML Response content-encoding will all match.
       */
      #endregion Notes
   }

   private XmlDocument GetXmlToShow(HttpContext context)
   {
      //Use context.Request to get the account number they want to return
      //GET /GetPatronInformation.ashx?accountNumber=619

      //Or since this is sample code, pull XML out of your rear:
      XmlDocument doc = new XmlDocument();
      doc.LoadXml("<Patron><Name>Rob Kennedy</Name></Patron>");

      return doc;
   }

   public bool IsReusable { get { return false; } }
}

이상적으로는 ASPX의 코드가 정상적인 실행을 가로 챌 수 있지만 XML을 보내려면 ashx를 사용하는 것이 좋습니다.

Response.Clear()

나는 당신이 이미 응답에 아무것도 버렸는지 확실하지 않다면 이것을 사용하지 않고 그것을 찾아서 제거하십시오.

Response.ContentType = "text/xml"

확실히 일반 클라이언트는이 콘텐츠 유형이 없으면 콘텐츠를 XML로 수락하지 않습니다.

 Response.Charset = "UTF-8";

응답 클래스가 컨텐츠 유형 헤더 작성을 적절하게 처리하도록하십시오. 정말로, 정말로 좋은 이유가 없다면 UTF-8을 사용하십시오.

Response.Cache.SetCacheability(HttpCacheability.NoCache);
Response.Cache.SetAllowResponseInBrowserHistory(true);

캐시 헤더를 보내지 않으면 일부 브라우저 (즉, IE)가 응답을 캐시하므로 후속 요청이 반드시 서버에 올 필요는 없습니다. (IE의 또 다른 버그로 인해) HTTPS를 통해 작동하게하려면 AllowResponseInBrowser도 필요합니다.

XmlDocument의 내용을 보내려면 다음을 사용하십시오.

dom.Save(Response.OutputStream);

dom.Save(Response.Output);

인코딩이 일치하는지 확인하십시오 (UTF-8을 사용하는 또 다른 좋은 이유).

XmlDocument객체는 자동으로 삽입 조정 것이다 encoding="..."의 것에 인코딩 Response(예 UTF-8)

Response.End()

ASPX에서 정말로 필요하지만 약간 과감하다면 ASHX에서는하지 마십시오.


아래는 내가 생각하는 올바른 방식의 예입니다. 적어도 내가 사용하는 것입니다. 이미 채워진 헤더를 제거하려면 Response.Clear를 수행해야합니다. text / xml의 올바른 ContentType을 전달해야합니다. 그것이 xml을 제공하는 방법입니다. 일반적으로 대부분의 파서가 예상하는 문자 세트 UTF-8로 제공하고 싶습니다. 하지만 그럴 필요는 없다고 생각합니다. 그러나 변경하면 xml 문서 선언을 변경하고 거기에 문자 집합을 표시하십시오. 기본 문자 집합이 아닌 UTF-8로 실제로 쓸 수 있도록 XmlWriter를 사용해야합니다. 그리고 XML 데이터를 UTF-8로 올바르게 인코딩하십시오.

   ' -----------------------------------------------------------------------------
   ' OutputDataSetAsXML
   '
   ' Description: outputs the given dataset as xml to the response object
   '
   ' Arguments:
   '    dsSource           - source data set
   '
   ' Dependencies:
   '
   ' History
   ' 2006-05-02 - WSR : created
   '
   Private Sub OutputDataSetAsXML(ByRef dsSource As System.Data.DataSet)

      Dim xmlDoc As System.Xml.XmlDataDocument
      Dim xmlDec As System.Xml.XmlDeclaration
      Dim xmlWriter As System.Xml.XmlWriter

      ' setup response
      Me.Response.Clear()
      Me.Response.ContentType = "text/xml"
      Me.Response.Charset = "utf-8"
      xmlWriter = New System.Xml.XmlTextWriter(Me.Response.OutputStream, System.Text.Encoding.UTF8)

      ' create xml data document with xml declaration
      xmlDoc = New System.Xml.XmlDataDocument(dsSource)
      xmlDoc.DataSet.EnforceConstraints = False
      xmlDec = xmlDoc.CreateXmlDeclaration("1.0", "UTF-8", Nothing)
      xmlDoc.PrependChild(xmlDec)

      ' write xml document to response
      xmlDoc.WriteTo(xmlWriter)
      xmlWriter.Flush()
      xmlWriter.Close()
      Response.End()

   End Sub
   ' -----------------------------------------------------------------------------

여기에 최소한 10 개의 질문이 하나에 포함 된 것 같습니다.

Response.Clear - it really depends on what else is going on in the app - if you have httpmodules early in the pipeline that might be writing stuff you don't want - then clear it. Test it and find out. Fiddler or Wireshark useful for this.

Content Type to text/xml - yup - good idea - read up on HTTP spec as to why this is important. IMO anyone doing web work should have read the 1.0 and 1.1 spec at least once.

Encoding - how is your xml encoded - if it is utf-8, then say so, if not, say something else appropriate, just make sure they all match.

Page - personally, would use ashx or httpmodule, if you are using page, and want it a bit faster, get rid of autoeventwireup and bind the event handlers manually.

Would probably be a bit of a waste of memory to dump the xml into a string first, but it depends a lot on the size of the xml as to whether you would ever notice.

As others have suggested, saving the xml to the output stream probably the fastest, I would normally do that, but if you aren't sure, test it, don't rely on what you read on the interweb. Don't just believe anything I say.

For another approach, if the xml doesn't change that much, you could just write it to the disk and serve the file directly, which would likely be quite performant, but like everything in programming, it depends...


I'm surprised that nobody seems to have ever mentioned that you can use XDocument / XElement which are available in .NET 4.0 and make it much easier to output XML.


Below is the server side code that would call the handler and recieve the stream data and loads into xml doc

 Stream stream = null;
       **Create a web request with the specified URL**
        WebRequest myWebRequest = WebRequest.Create(@"http://localhost/XMLProvider/XMLProcessorHandler.ashx");
        **Senda a web request and wait for response.**
        WebResponse webResponse = myWebRequest.GetResponse();
        **Get the stream object from response object**
        stream = webResponse.GetResponseStream();

       XmlDocument xmlDoc = new XmlDocument();
      **Load stream data into xml**
       xmlDoc.Load(stream);

Below is the way a handler will returns stream data that would contain xml data in the server side.

Here is the handler code that would returns the data.

    public void ProcessRequest(HttpContext context)
    {

        StringBuilder xmlBuilder = new StringBuilder();

        xmlBuilder.Append("<Names>");
        xmlBuilder.Append("<Name>");
        xmlBuilder.Append("Sheo");
        xmlBuilder.Append("</Name>");
        xmlBuilder.Append("</Names>");
        context.Response.ContentType = "application/octet-stream";
        context.Response.BinaryWrite(Encoding.UTF8.GetBytes(xmlBuilder.ToString()));
        context.Response.End();

    }

XmlDocument xd = new XmlDocument();
xd.LoadXml(xmlContent);

context.Response.Clear();
context.Response.ContentType = "text/xml";
context.Response.ContentEncoding = System.Text.Encoding.UTF8;
xd.Save(context.Response.Output);
context.Response.Flush();
context.Response.SuppressContent = true;
context.ApplicationInstance.CompleteRequest();

You've basically answered anything and everything already, so I'm no sure what the point is here?

FWIW I would use an httphandler - there seems no point in invoking a page lifecycle and having to deal with clipping off the bits of viewstate and session and what have you which don't make sense for an XML doc. It's like buying a car and stripping it for parts to make your motorbike.

And content-type is all important, it's how the requester knows what to do with the response.

ReferenceURL : https://stackoverflow.com/questions/543319/how-to-return-xml-in-asp-net

반응형