C# 如何在ASP.NET中返回XML?
对于在ASP.NET中返回XML的任务,我遇到了许多半途而废的解决方案。不过,我不想盲目地复制和粘贴一些大部分时间都能正常工作的代码;我想要正确的代码,我想知道为什么它是正确的。我要批评;我想要信息;我想要知识;我需要理解 下面是代码片段,按照复杂性的增加顺序,代表了我所看到的部分解决方案,包括每种解决方案引起的一些进一步的问题,我想在这里回答这些问题 一个彻底的答案必须说明为什么我们必须拥有或不拥有以下任何东西,或者解释为什么它是不相关的C# 如何在ASP.NET中返回XML?,c#,asp.net,xml,C#,Asp.net,Xml,对于在ASP.NET中返回XML的任务,我遇到了许多半途而废的解决方案。不过,我不想盲目地复制和粘贴一些大部分时间都能正常工作的代码;我想要正确的代码,我想知道为什么它是正确的。我要批评;我想要信息;我想要知识;我需要理解 下面是代码片段,按照复杂性的增加顺序,代表了我所看到的部分解决方案,包括每种解决方案引起的一些进一步的问题,我想在这里回答这些问题 一个彻底的答案必须说明为什么我们必须拥有或不拥有以下任何东西,或者解释为什么它是不相关的 Response.Clear() Response.
- Response.Clear()李>
- Response.ContentType=“text/xml”李>
- Response.ContentEncoding=Encoding.UTF8李>
- Response.ContentEncoding=Encoding.UTF16李>
- Response.ContentType=“text/xml;charset=utf-8”李>
- Response.ContentType=“text/xml;charset=utf-16”李>
- 答复:End()
- 使用aspx,前面的文件内脏被撕掉
- 使用ashx文件
///在(Page_Xxx)方法中使用此调用来编写
///将xml转换为web客户端。
///寻找https://stackoverflow.com/questions/543319/how-to-return-xml-in-asp-net
///正确使用。
公共静态无效返回XmlDocumentToWebClient(
XmlDocument文件,
第页(共页)
{
...
}
我看到的每个解决方案都是从获取一个空的aspx页面开始,并从前面的文件中删除所有HTML(这会在Visual Studio中引起警告):
我们是否需要将内容类型更改为“text/xml”?即:
受保护的无效页面加载(对象发送方,事件参数e)
{
String xml=“你好,世界!”;
Response.ContentType=“text/xml”;
Response.Write(xml);
}
我们是否需要调用
响应。首先清除
受保护的无效页面加载(对象发送方,事件参数e)
{
String xml=“你好,世界!”;
Response.Clear();
Response.ContentType=“text/xml”;
Response.Write(xml);
}
我们真的需要这样称呼吗?没有响应。清除使前一步确保前面文件中的代码在
之外为空(甚至没有空格或回车符)成为不必要的
Response.Clear
是否使其更加健壮,以防有人在代码前端文件中留下空行或空格
使用ashx是否与空白的aspx主文件相同,因为它不会输出HTML
我们是否需要调用Response.End
?即:
受保护的无效页面加载(对象发送方,事件参数e)
{
String xml=“你好,世界!”;
Response.Clear();
Response.ContentType=“text/xml”;
Response.Write(xml);
Response.End();
}
在响应之后还可能发生什么。请编写需要我们立即结束响应的
text/xml
的内容类型是否足够,还是应该改为text/xml;字符集=utf-8
受保护的无效页面加载(对象发送方,事件参数e)
{
String xml=“你好,世界!”;
Response.Clear();
Response.ContentType=“text/xml;charset=utf-8”;
Response.Write(xml);
Response.End();
}
还是应该明确地而不是?在内容类型中使用字符集,但不设置属性,是否会使服务器出错
为什么不选择其他内容类型,例如:
- UTF-8
- utf-16
- UTF-16
是否应在Response.ContentEncoding
中指定字符集
受保护的无效页面加载(对象发送方,事件参数e)
{
String xml=“你好,世界!”;
Response.Clear();
Response.ContentType=“text/xml”;
Response.ContentEncoding=Encoding.UTF8;
Response.Write(xml);
Response.End();
}
使用Response.ContentEncoding
比将其塞进Response.ContentType
要好吗?更糟吗?前者是否得到支持?是后者吗
我其实不想写一个字符串;我想写一个XmlDocument
:
受保护的无效页面加载(对象发送方,事件参数e)
{
XmlDocument xml=GetXmlDocumentToShowTheUser();
Response.Clear();
Response.ContentType=“text/xml”;
Response.ContentEncoding=Encoding.UTF8;
使用(TextWriter TextWriter=新StreamWriter)(
Response.OutputStream,
编码(UTF8)
{
XmlTextWriter xmlWriter=新的XmlTextWriter(textWriter);
//使用xmlWriter编写XML
//TODO:怎么做?
}
}
注意使用Response.OutputStream
,而不是Response.Write
。这个好吗?糟糕?更好?更糟的更快?更慢的?内存更密集?更少的内存密集型
我希望你能
页面的Render()方法中的XML
避免分块问题
使用页面加载()时遇到
什么是组块?
分块有什么问题,使用Page\u Render
如何消除这些问题
我不想将XmlDocument
对象的内容写入字符串,然后再写入,因为这样会浪费内存。也就是说,其中任何一项都是不好的:
Response.Write(doc.ToString());
Response.Write(doc.InnerXml);
WriteString(doc.ToString());
WriteString(doc.InnerXml);
类似问题
参考资料
你基本上已经回答了所有的问题,所以我不确定这里的重点是什么
FWIW我会使用一个httphandler——调用页面生命周期并处理裁剪viewstate的部分似乎没有任何意义
<%@ Page Language="C#"
AutoEventWireup="true"
CodeFile="GetTheXml.aspx.cs"
Inherits="GetTheXml" %>
Response.Clear()
Response.ContentType = "text/xml"
Response.Charset = "UTF-8";
Response.Cache.SetCacheability(HttpCacheability.NoCache);
Response.Cache.SetAllowResponseInBrowserHistory(true);
dom.Save(Response.OutputStream);
dom.Save(Response.Output);
Response.End()
' -----------------------------------------------------------------------------
' 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
' -----------------------------------------------------------------------------
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)
<?xml version="1.0" encoding="ISO-8859-1"?>
<?xml version="1.0" encoding="UTF-8"?>
doc.Save(Response.OutputStream);
doc.Save(Response.Output);
Response.ContentEncoding = ...
<?xml version="1.0" encoding="..."?>
Response.ContentEncoding = System.Text.Encoding.UTF8;
<?xml version="1.0" encoding="UTF-8"?>
doc.Save(someTextWriter);
doc.Save(Response.OutputStream);
Response.Write(doc.ToString());
Response.Write(doc.InnerXml);
- doesn't follow the encoding specified
- doesn't set the XML declaration node to match
- wastes memory
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
<%@ 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 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; } }
}
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();
}
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);
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();