jjzjj

ASP.NET:将 XmlDocument 保存到 Response.OutputStream 会遵守编码吗?

coder 2024-06-26 原文

我想将 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?

或者 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");

最佳答案

我找到了。

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

更新:正确的方法

  • 使用 Response.Output 而不是 Response.OutputStream

    两者都是流,但 OutputTextWriter

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



    匹配 Response.Output 的编码设置使用的编码。
  • Response.Output TextWriter 的编码设置来自Response.ContentEncoding 值。
  • 使用 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 编码。

    如果没有指定编码,例如:
    <?xml version="1.0"?>
    

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

    If an encoding attribute is not included, UTF-8 encoding is assumed when the document is written or saved out.



    您也可以在 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

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

    Unlike most XML attributes, encoding attribute values are not case-sensitive. This is because encoding character names follow ISO and Internet Assigned Numbers Authority (IANA) standards.



    如果从字符串或文件加载 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 声明没有 encoding 属性,则保存的文档也不会有一个。

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

    The encoding on the TextWriter determines the encoding that is written out (The encoding of the XmlDeclaration node is replaced by the encoding of the TextWriter). If there was no encoding specified on the TextWriter, the XmlDocument is saved without an encoding attribute.



    如果保存为字符串,则使用的编码由 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>
    

    关于ASP.NET:将 XmlDocument 保存到 Response.OutputStream 会遵守编码吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/546994/

    有关ASP.NET:将 XmlDocument 保存到 Response.OutputStream 会遵守编码吗?的更多相关文章

    1. ruby-on-rails - Ruby net/ldap 模块中的内存泄漏 - 2

      作为我的Rails应用程序的一部分,我编写了一个小导入程序,它从我们的LDAP系统中吸取数据并将其塞入一个用户表中。不幸的是,与LDAP相关的代码在遍历我们的32K用户时泄漏了大量内存,我一直无法弄清楚如何解决这个问题。这个问题似乎在某种程度上与LDAP库有关,因为当我删除对LDAP内容的调用时,内存使用情况会很好地稳定下来。此外,不断增加的对象是Net::BER::BerIdentifiedString和Net::BER::BerIdentifiedArray,它们都是LDAP库的一部分。当我运行导入时,内存使用量最终达到超过1GB的峰值。如果问题存在,我需要找到一些方法来更正我的代

    2. ruby - 什么是填充的 Base64 编码字符串以及如何在 ruby​​ 中生成它们? - 2

      我正在使用的第三方API的文档状态:"[O]urAPIonlyacceptspaddedBase64encodedstrings."什么是“填充的Base64编码字符串”以及如何在Ruby中生成它们。下面的代码是我第一次尝试创建转换为Base64的JSON格式数据。xa=Base64.encode64(a.to_json) 最佳答案 他们说的padding其实就是Base64本身的一部分。它是末尾的“=”和“==”。Base64将3个字节的数据包编码为4个编码字符。所以如果你的输入数据有长度n和n%3=1=>"=="末尾用于填充n%

    3. ruby - 用逗号、双引号和编码解析 csv - 2

      我正在使用ruby​​1.9解析以下带有MacRoman字符的csv文件#encoding:ISO-8859-1#csv_parse.csvName,main-dialogue"Marceu","Giveittohimóhe,hiswife."我做了以下解析。require'csv'input_string=File.read("../csv_parse.rb").force_encoding("ISO-8859-1").encode("UTF-8")#=>"Name,main-dialogue\r\n\"Marceu\",\"Giveittohim\x97he,hiswife.\"\

    4. ruby - 如何模拟 Net::HTTP::Post? - 2

      是的,我知道最好使用webmock,但我想知道如何在RSpec中模拟此方法:defmethod_to_testurl=URI.parseurireq=Net::HTTP::Post.newurl.pathres=Net::HTTP.start(url.host,url.port)do|http|http.requestreq,foo:1endresend这是RSpec:let(:uri){'http://example.com'}specify'HTTPcall'dohttp=mock:httpNet::HTTP.stub!(:start).and_yieldhttphttp.shou

    5. C# 到 Ruby sha1 base64 编码 - 2

      我正在尝试在Ruby中复制Convert.ToBase64String()行为。这是我的C#代码:varsha1=newSHA1CryptoServiceProvider();varpasswordBytes=Encoding.UTF8.GetBytes("password");varpasswordHash=sha1.ComputeHash(passwordBytes);returnConvert.ToBase64String(passwordHash);//returns"W6ph5Mm5Pz8GgiULbPgzG37mj9g="当我在Ruby中尝试同样的事情时,我得到了相同sha

    6. ruby - Net::HTTP 获取源代码和状态 - 2

      我目前正在使用以下方法获取页面的源代码:Net::HTTP.get(URI.parse(page.url))我还想获取HTTP状态,而无需发出第二个请求。有没有办法用另一种方法做到这一点?我一直在查看文档,但似乎找不到我要找的东西。 最佳答案 在我看来,除非您需要一些真正的低级访问或控制,否则最好使用Ruby的内置Open::URI模块:require'open-uri'io=open('http://www.example.org/')#=>#body=io.read[0,50]#=>"["200","OK"]io.base_ur

    7. Get https://registry-1.docker.io/v2/: net/http: request canceled while waiting - 2

      1.错误信息:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:requestcanceledwhilewaitingforconnection(Client.Timeoutexceededwhileawaitingheaders)或者:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:TLShandshaketimeout2.报错原因:docker使用的镜像网址默认为国外,下载容易超时,需要修改成国内镜像地址(首先阿里

    8. .net - .NET 将如何影响 Python 和 Ruby 应用程序? - 2

      我很好奇.NET将如何影响Python和Ruby应用程序。用IronPython/IronRuby编写的应用程序是否会非常特定于.NET环境,以至于它们实际上将变得特定于平台?如果他们不使用任何.NET功能,那么IronPython/IronRuby相对于非.NET同类产品的优势是什么? 最佳答案 我不能说任何关于IronRuby的东西,但是大多数Python实现(如IronPython、Jython和PyPy)都试图尽可能忠实于CPython实现。不过,IronPython正在迅速成为这方面的佼佼者之一,并且在PlanetPyth

    9. ruby-on-rails - 有没有一种工具可以在编码时自动保存对文件的增量更改? - 2

      我最喜欢的Google文档功能之一是它会在我工作时不断自动保存我的文档版本。这意味着即使我在进行关键更改之前忘记在某个点进行保存,也很有可能会自动创建一个保存点。至少,我可以将文档恢复到错误更改之前的状态,并从该点继续工作。对于在MacOS(或UNIX)上运行的Ruby编码器,是否有具有等效功能的工具?例如,一个工具会每隔几分钟自动将Gitcheckin我的本地存储库以获取我正在处理的文件。也许我有点偏执,但这点小保险可以让我在日常工作中安心。 最佳答案 虚拟机有些人可能讨厌我对此的回应,但我在编码时经常使用VIM,它具有自动保存功

    10. ruby-on-rails - 使用 HTTP.get_response 检索 Facebook 访问 token 时出现 Rails EOF 错误 - 2

      我试图在我的网站上实现使用Facebook登录功能,但在尝试从Facebook取回访问token时遇到障碍。这是我的代码:ifparams[:error_reason]=="user_denied"thenflash[:error]="TologinwithFacebook,youmustclick'Allow'toletthesiteaccessyourinformation"redirect_to:loginelsifparams[:code]thentoken_uri=URI.parse("https://graph.facebook.com/oauth/access_token

    随机推荐