Мне удалось добавить несколько файлов cookie в исходящий ответ службы WCF, добавив атрибут «Set-Cookie» в заголовок ответа. Он отлично работает, и cookie доступен во всех последующих запросах, только если есть один cookie, но не для нескольких cookie. Пожалуйста, ознакомьтесь с моей реализацией ниже. Я добавляю файлы cookie в заголовок ответа, реализуя интерфейс IDispatchMessageInspector, чтобы добавить файлы cookie во все вызовы метода службы WCF, если в ответе есть какие-либо ожидающие обновления файлы cookie.
Пример вывода файлов cookie в заголовок ответа и заголовок запроса
1 Cookie: foo = testcookie1; путь = / -> доступен во всех последующих вызовах запроса
2 или более файлов cookie: foo = testcookie1; путь = / ;, foo2 = testcookie2; путь = / ;, foo3 = testcookie3; path = /; -> -> только первый файл cookie, доступный во всех последующих вызовах запроса, но не другие
Например:
после установки файлов cookie мой заголовок ответа будет выглядеть так: Set-Cookie: foo1 = testcookie1;, foo2 = testcookie2 ;, foo3 = testcookie3; . Если я сделаю еще один запрос, то cookie заголовка запроса будет содержать только foo1 = testcookie1; , но не эти файлы cookie foo2 = testcookie2; foo3 = testcookie3; . Это где проблема приходит. Если в заголовке ответа я установил более одного файла 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));
}
}
}