【问题标题】:ASP.NET: Will Saving an XmlDocument to the Response.OutputStream honor the encoding?ASP.NET:将 XmlDocument 保存到 Response.OutputStream 是否尊重编码?
【发布时间】:2009-02-13 18:00:43
【问题描述】:

我想将XmlDocument 对象的xml 发送到HTTP 客户端,但我担心suggested soltuion 可能不支持Response 已设置使用的编码:

public void ProcessRequest(HttpContext context)
{
   XmlDocument doc = GetXmlToShow(context);

   context.Response.ContentType = "text/xml";
   context.Response.ContentEncoding = System.Text.Encoding.UTF8;
   context.Response.Cache.SetCacheability(HttpCacheability.NoCache);
   context.Response.Cache.SetAllowResponseInBrowserHistory(true);

   doc.Save(context.Response.OutputStream);

}

如果我将编码更改为其他内容,例如 Unicode

public void ProcessRequest(HttpContext context)
{
   XmlDocument doc = GetXmlToShow(context);

   context.Response.ContentType = "text/xml";
   context.Response.ContentEncoding = System.Text.Encoding.Unicode;
   context.Response.Cache.SetCacheability(HttpCacheability.NoCache);
   context.Response.Cache.SetAllowResponseInBrowserHistory(true);

   doc.Save(context.Response.OutputStream);
}

Response.OutputStream 是否会即时翻译正在写入它的二进制数据,并使其成为 Unicode?​​p>

或者Response.ContentEncoding 只是信息性

如果 ContentEncoding 只是提供信息,那么后面的文本字符串将以什么内容编码返回?

context.Response.ContentEncoding = System.Text.Encoding.Unicode;
context.Response.Write("Hello World");

context.Response.ContentEncoding = System.Text.Encoding.UTF8;
context.Response.Write("Hello World");

context.Response.ContentEncoding = System.Text.Encoding.UTF16;
context.Response.Write("Hello World");

context.Response.ContentEncoding = System.Text.Encoding.ASCII;
context.Response.Write("Hello World");

context.Response.ContentEncoding = System.Text.Encoding.BigEndianUnicode;
context.Response.Write("Hello World");

【问题讨论】:

    标签: asp.net xml unicode xmldocument


    【解决方案1】:

    我找到了。

    答案是否定的:XmlDocument 不会遵守它正在写入的响应流的 ContentEncoding。


    更新:正确的做法

    1. 使用Response.Output不使用 Response.OutputStream

      两者都是流,但OutputTextWriter

      XmlDocument 将自己保存到TextWriter 时,它将使用编码 由TextWriter 指定。 XmlDocument 将自动更改任何 xml声明节点,即:

      匹配Response.Output的编码设置所使用的编码。

    2. Response.OutputTextWriter 的编码设置来自 Response.ContentEncoding 值。

    3. 使用doc.Save Response.Write(doc.ToString())Response.Write(doc.InnerXml)

      不要想要将 xml 保存到字符串中,或​​者将 xml 填充到字符串中, 还有response.Write那个,因为那个:

      • 不遵循指定的编码
      • 浪费内存

    总结一下:通过保存到TextWriter:XML 声明节点,XML 内容, 并且 HTML 响应内容编码将全部匹配。

    示例代码:

    public class Handler : IHttpHandler, System.Web.SessionState.IRequiresSessionState 
    {
        //Note: We add IRequiesSessionState so that we'll have access to context.Session object
        //Otherwise it will be null
    
    
        public void ProcessRequest(HttpContext context)
        {
            XmlDocument doc = GetXmlToShow(context); //GetXmlToShow will look for parameters from the context
    
            if (doc != null)
            {
                context.Response.ContentType = "text/xml"; //must be 'text/xml'
                context.Response.ContentEncoding = System.Text.Encoding.UTF8; //we'd like utf-8
                doc.Save(context.Response.Output); //doc save 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
        }
    
        public bool IsReusable { get { return false; } }
    }
    

    XmlDocument 保存到流时使用的编码取决于 xml 声明节点 中指定的编码。例如:

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

    如果在 xml 声明中指定了“UTF-8”编码,那么 Save(stream) 将使用 UTF-8 编码。

    如果 no 指定编码,例如:

    <?xml version="1.0"?>
    

    或完全省略xml声明节点,则XmlDocument将默认为UTF-8 unicode编码。 (Reference)

    如果编码属性不是 包括在内,假定为 UTF-8 编码 写入或保存文档时 出去。

    Some common encodings strings,您也可以在 xml 声明中使用:

    • UTF-8
    • UTF-16
    • ISO-10646-UCS-2
    • ISO-10646-UCS-4
    • ISO-8859-1
    • ISO-8859-2
    • ISO-8859-3
    • ISO-8859-4
    • ISO-8859-5
    • ISO-8859-6
    • ISO-8859-7
    • ISO-8859-8
    • ISO-8859-9
    • ISO-2022-JP
    • Shift_JIS
    • EUC-JP

    注意:编码属性不区分大小写:

    与大多数 XML 属性不同,编码 属性值不是 区分大小写。这是因为 编码字符名称遵循 ISO 和互联网分配号码 权威 (IANA) 标准。

    如果您从字符串或文件加载 XML,并且它不包含 xml 声明节点,您可以 manually add one to the XmlDocument 使用:

    // Create an XML declaration. 
    XmlDeclaration xmldecl;
    xmldecl = doc.CreateXmlDeclaration("1.0", null, null);
    xmldecl.Encoding="UTF-8";
    
    // Add the new node to the document.
    XmlElement root = doc.DocumentElement;
    doc.InsertBefore(xmldecl, root);
    

    如果 XmlDocument 没有 xml 声明,或者 xml 声明没有编码属性,则保存的文档也不会有。

    注意:如果 XmlDocument 保存到 TextWriter,则将使用的编码取自 TextWriter 对象。此外,当内容写入 TextWriter 时,xml 声明节点编码属性(如果存在)将替换为 TextWriter 的编码。 (Reference)

    TextWriter 上的编码 确定编码是 写出(的编码 XmlDeclaration 节点被替换为 TextWriter 的编码)。如果有 没有指定编码 TextWriter,XmlDocument 被保存 没有编码属性。

    如果保存为字符串,则使用的编码由 xml 声明节点的编码属性(如果存在)确定。


    在我的具体示例中,我正在通过 ASP.NET 写回 Http 客户端。我想将 Response.Encoding 类型设置为适当的值 - 我需要匹配 XML 本身将包含的内容。

    执行此操作的适当方法是将 xml 保存到 Response.Output,而不是 Response.OutputStream。 Response.Output 是一个 TextWriter,其 Encoding 值遵循您为 Response.Encoding 设置的值。

    换句话说:

    context.Response.ContentEncoding = System.Text.Encoding.ASCII;
    doc.Save(context.Response.Output);
    

    xml 中的结果:

    <?xml version="1.0" encoding="us-ascii" ?> 
    <foo>Hello, world!</foo>
    

    同时:

    context.Response.ContentEncoding = System.Text.Encoding.UTF8;
    doc.Save(context.Response.Output);
    

    xml 中的结果:

    <?xml version="1.0" encoding="utf-8" ?> 
    <foo>Hello, world!</foo>
    

    context.Response.ContentEncoding = System.Text.Encoding.Unicode;
    doc.Save(context.Response.Output);
    

    xml 中的结果:

    <?xml version="1.0" encoding="utf-16" ?> 
    <foo>Hello, world!</foo>
    

    【讨论】:

      【解决方案2】:

      来自 google 的前 2 个链接

      如何:为 ASP.NET 网页全球化选择编码: http://msdn.microsoft.com/en-us/library/hy4kkhe0.aspx

      全球化元素(ASP.NET 设置架构): http://msdn.microsoft.com/en-us/library/hy4kkhe0.aspx

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-04-24
        • 2012-09-22
        • 1970-01-01
        • 2019-02-17
        • 2013-08-18
        • 2021-05-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多