【问题标题】:WCF 4.0 Cookie Only First is Recorded by Browser浏览器仅首先记录 WCF 4.0 Cookie
【发布时间】:2012-04-19 03:22:26
【问题描述】:

我正在研究使用 WebHttpBinding 从 WCF 自托管控制台应用程序 REST 服务写入 cookie 的最快方法。 我准备了“Set Cookies”,但只在浏览器中设置了第一个 cookie(在 Windows 上使用 FireFox 11.0)以及“Expires”值。

var expiry = DateTime.Now.AddMonths( 6 );
var outresp = WebOperationContext.Current.OutgoingResponse;
outresp.Headers.Add( HttpResponseHeader.SetCookie , "cookie1=fd9416ea-2705-4d44-be76-f2f7b95e6b13; cookie2=7d489e69-d9c9-4b8d-a4b1-bce0da1c5966;expires=" + expiry );

我还尝试在第一个 cookie 和第二个 cookie 之间加一个逗号,但也没有用:

outresp.Headers.Add( HttpResponseHeader.SetCookie , "cookie1=fd9416ea-2705-4d44-be76-f2f7b95e6b13;, cookie2=7d489e69-d9c9-4b8d-a4b1-bce0da1c5966;expires=" + expiry );

我把它删掉了,然后启动了 Fiddler:

outresp.Headers.Add( HttpResponseHeader.SetCookie , "foo=foovalue;,bar=barvalue;" );

Fiddler 展示了这一点:

Response sent 27 bytes of Cookie data:
    Set-Cookie: foo=foovalue;,bar=barvalue;

This response did not contain a P3P Header.

Validate P3P Policies at: http://www.w3.org/P3P/validator.html
Learn more at: http://www.fiddler2.com/redir/?id=p3pinfo

这告诉我,我没有在 .NET 端格式化东西以使浏览器可以接受 cookie。

我怎样才能将所有的 cookie 放入浏览器的第一个值的 insetad 中?我错过了什么?

谢谢。

[编辑]

我将此问题提交给 Microsoft 寻求支持,并了解到这一点:

“Set-Cookie”被合并到单个 cookie 行中的事实在 Microsoft 中被记录为 .NET Framework 4.0 和 Framework 4.5 的错误。 在 Microsoft WCF 开发组中,该错误被列为“已关闭”且“无法修复”。
根据微软的说法,唯一的解决方法是从自托管转移到在 IIS 内托管,然后直接使用 (IIS) 响应对象(没有错误的不同代码路径)。

【问题讨论】:

  • 提供服务配置、服务接口、服务类属性和方法属性可能会有帮助。
  • 另外,包括您的主机配置和代码。

标签: wcf rest cookies


【解决方案1】:

虽然这是一篇较早的帖子,但由于这仍然是一个持续存在的问题,并且将 AspNetCompatibilityMode 与 WCF 一起使用会显着降低性能,因此 MSFT 提供的选项在许多/大多数/任何情况下都不可行。由于这个问题仍然挥之不去,我将晚点回答这个问题。

解决此问题的唯一方法是像您显示的那样输出 Set-Cookie 响应标头,但在客户端使用 javascript 处理该响应标头并将其放入浏览器,因为您已经注意到,浏览器不会处理这个响应。正如我创建的这个错误中所述,应用多个 Set-Cookie 响应标头都不会起作用。

http://connect.microsoft.com/VisualStudio/feedback/details/779111/wcf-rest-service-two-set-cookie-http-headers-invalid-set-cookie-header-syntax

因此,处理响应标头并使用客户端 javascript 中的 document.cookie 将 cookie 放置在浏览器中的 jQuery .ajax 请求的成功处理程序中。

【讨论】:

    【解决方案2】:

    为了扩展@jeff-fischer 的答案,AspNetCompatibilityMode 确实有效,并且需要以下内容:

    AspNetCompatibilityRequirements 为服务类设置为AllowedRequired 例如:

    [AspNetCompatibilityRequirements(RequirementsMode
           = AspNetCompatibilityRequirementsMode.Allowed)]
    public class AppService : IAppService
    

    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" /> 设置在<system.serviceModel>

    然后可以访问HttpContext(您需要using System.Web; 才能访问)并且可以使用以下方式设置cookie:

    var aCookie = new HttpCookie("foo")
    {
        HttpOnly = true,
        Value = "bar",
        Expires = DateTime.Now.AddDays(1)
    };
    
    HttpContext.Current.Response.Cookies.Add(aCookie);
    

    这需要在 IIS 上作为应用程序运行,而不是通过 WCF 启动器运行,如果设置了多个 cookie,实际上会出现多个 cookie 标头。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-08-12
      • 1970-01-01
      • 2015-06-14
      • 2014-08-29
      • 2023-03-17
      • 1970-01-01
      • 2021-10-13
      • 1970-01-01
      相关资源
      最近更新 更多