ASP.NET:将一个XmlDocument保存到Response.OutputStream是否符合编码?

时间:2009-02-13 18:00:43

标签: asp.net xml unicode xmldocument

我想将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); 的编码使用方法:

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

}

如果我将编码更改为其他内容,例如 Unicode ,该怎么办?

Response.OutputStream

Response.ContentEncoding是否会即时翻译正在写入的二进制数据,并将其设为Unicode?

或者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"); 只是信息

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

{{1}}

2 个答案:

答案 0 :(得分:14)

我找到了。

答案是否定的:XmlDocument不会尊重它写入的响应流的ContentEncoding。


更新:正确的方法

  1. 使用Response.Output Response.OutputStream

    两者都是流,但OutputTextWriter

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

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

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

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

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

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

    • 不遵循指定的编码
    • 浪费记忆
  4. 总结:通过保存到TextWriter:XML声明节点,XML内容, 并且HTML Response内容编码将全部匹配。

    示例代码:

    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声明节点中指定的编码。 e.g:

         <?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编码   写入或保存文档时   进行。

    你也可以在xml声明中使用的

    Some common encodings strings是:

    • 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,其编码值遵循您为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>
    

答案 1 :(得分:-1)

来自谷歌的前2个链接

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

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