wcf - 在 WCF 服务中将多个 cookie 添加到响应的问题

标签 wcf setcookie

通过在响应 header 中添加“Set-Cookie”属性,我设法在 WCF 服务传出响应中添加了多个 cookie。它工作得很好,只有当有一个 cookie 而不是多个 cookie 时,cookie 才可在所有后续请求中使用。请引用我下面的实现。我通过实现 IDispatchMessageInspector 接口(interface)将 cookie 添加到响应 header 中,以便在响应中更新任何挂起的 cookie 时在所有 WCF 服务方法调用中添加 cookie。

响应 header 和请求 header 中的 Cookie 输出示例

1 个 cookies :富=testcookie1;路径=/ --> 在所有后续请求调用中可用
2 个或更多 cookie:富=testcookie1;路径=/;, foo2=testcookie2;路径=/;, foo3=testcookie3;路径=/; --> --> 仅在所有后续请求调用中可用的第一个 cookie,但在其他请求调用中不可用

例如:

设置 cookie 后,我的响应标题将类似于 Set-Cookie: foo1=testcookie1;,foo2=testcookie2;, foo3=testcookie3; .如果我发出另一个请求,则请求 header cookie 仅包含 foo1=testcookie1; 但不是这些 cookie foo2=testcookie2; foo3=testcookie3; .这就是问题所在。如果我在响应 header 中设置了多个 cookie,那么在后续请求调用中它总是只使用第一个 cookie。

请帮我解决这个问题。提前感谢您的友好回复。

执行

public class CookieManagerServiceBehaviorAttribute : Attribute, IServiceBehavior
{
    #region IServiceBehavior Members
    public void AddBindingParameters(ServiceDescription serviceDescription, System.ServiceModel.ServiceHostBase serviceHostBase, System.Collections.ObjectModel.Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters)
    {
        return;
    }

    public void ApplyDispatchBehavior(ServiceDescription serviceDescription, System.ServiceModel.ServiceHostBase serviceHostBase)
    {
        foreach (ChannelDispatcher channelDispatch in serviceHostBase.ChannelDispatchers)
        {
            foreach (EndpointDispatcher endpointDispatch in channelDispatch.Endpoints)
            {
                endpointDispatch.DispatchRuntime.MessageInspectors.Add(CookieManagerMessageInspector.Instance);
            }
        }
    }

    public void Validate(ServiceDescription serviceDescription, System.ServiceModel.ServiceHostBase serviceHostBase)
    {
        return;
    }
    #endregion
}

public class CookieManagerMessageInspector : IDispatchMessageInspector
{
    private static CookieManagerMessageInspector instance;
    private CookieManagerMessageInspector() { }
    public static CookieManagerMessageInspector Instance
    {
        get
        {
            if (instance == null)
            {
                instance = new CookieManagerMessageInspector();
            }
            return instance;
        }
    }

    public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
    {
        return null;
    }

    public void BeforeSendReply(ref Message reply, object correlationState)
    {
        HttpResponseMessageProperty httpResponse;
        if (!reply.Properties.ContainsKey(HttpResponseMessageProperty.Name))
        {
            reply.Properties.Add(HttpResponseMessageProperty.Name, new HttpResponseMessageProperty());
        }
        httpResponse = (HttpResponseMessageProperty)reply.Properties[HttpResponseMessageProperty.Name];
        foreach (Cookie cookie in RenderContext.Current.PendingCookies)
        {
            if (cookie.Expires > DateTime.Now)
                httpResponse.Headers.Add(HttpResponseHeader.SetCookie, "{0}={1}; expires={2}".StringFormat(cookie.Name, cookie.Value, DateTime.Now.AddYears(1).ToUniversalTime()) + ";");
            else
                httpResponse.Headers.Add(HttpResponseHeader.SetCookie, "{0}={1};".StringFormat(cookie.Name, cookie.Value));
        }
    }
}

最佳答案

在构建网络代理时,我遇到了同样的问题。我需要将 Set-Cookie header 从目标 HttpWebResponse 中继到代理 HttpListenerResponse。如果 Set-Cookie header 中有多个 cookie,则只有第一个会在浏览器中注册。

当我遍历 header 的一组值(或者在您的情况下是 Cookie 的集合)并使用 response.AppendHeader(header, value) 表单时,我能够让它工作。

string[] cookies = response.Headers.GetValues("Set-Cookie");
foreach (string value in cookies)
    clientResponse.AppendHeader("Set-Cookie", value);

因此,在您的情况下,我会将代码的结尾更改为:
if (cookie.Expires > DateTime.Now)
     httpResponse.AppendHeader(HttpResponseHeader.SetCookie, "{0}={1}; expires={2}".StringFormat(cookie.Name, cookie.Value, DateTime.Now.AddYears(1).ToUniversalTime()) + ";");
else
     httpResponse.AppendHeader(HttpResponseHeader.SetCookie, "{0}={1};".StringFormat(cookie.Name, cookie.Value));

关于wcf - 在 WCF 服务中将多个 cookie 添加到响应的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5144354/

相关文章:

php - 重启浏览器后 Cookie 被删除

reactjs - 如何在reactjs中获取服务器发送的JWT cookie

asp.net-mvc - 同一子域下的azure wcf和mvc

c# - 我可以根据 URL 和方法名称调用 Web 服务吗?

c# - BackgroundWorker 是保持 WCF/WPF 应用程序响应的唯一方法吗?

c# - 托管*稳定* WCF MSMQ Windows 服务的正确方法

wcf - 如何从身份验证代理后面运行 svcutil.exe

php - 每次加载页面时,使用新值更新存储在 cookie 中的数组