C# 在哪里设置服务引用上的CookieContainer?
例如,在.NET 2.0项目中将WebService引用添加到ASMX服务时C# 在哪里设置服务引用上的CookieContainer?,c#,web-services,asmx,service-reference,web-reference,C#,Web Services,Asmx,Service Reference,Web Reference,例如,在.NET 2.0项目中将WebService引用添加到ASMX服务时 var objService = new NameSpace.groupservices(); var objService = new NameSpace.groupservicesSoapClient(); 有, objService.CookieContainer = new System.Net.CookieContainer(); 例如,将ServiceReference添加到.NET 4.0项目上的A
var objService = new NameSpace.groupservices();
var objService = new NameSpace.groupservicesSoapClient();
有,
objService.CookieContainer = new System.Net.CookieContainer();
例如,将ServiceReference添加到.NET 4.0项目上的ASMX服务时
var objService = new NameSpace.groupservices();
var objService = new NameSpace.groupservicesSoapClient();
objService没有任何CookieContainer属性
提出了一个类似的问题,但没有得到积极的解决
有人能告诉我在哪里可以找到酒店吗?在这里找到了解决方案:
事实证明,我需要一个web引用而不是服务引用。与绑定到HTTP传输的ASMX web服务相比,WCF允许使用各种传输协议。因此,并非所有特定于协议的选项(如HTTP传输的cookie)都可以在WCF服务引用中使用 但是,您可以添加一个消息检查器,用于检查在客户端和服务器之间发送的消息。这描述了一种向服务器发送cookie的方法 我已经扩展了示例以使用CookieContainer。另外,下面的代码显示了如何评估服务器发送的
Set Cookie
头,以将新Cookie添加到容器中。请注意,该示例显示了一个基本轮廓,但可能需要扩展或更多验证。然而,在一个简单的场景中,它起了作用
以下代码段显示了托管在IIS上并集成在ASP.NET framework中的WCF服务的测试方法。它基本上以字符串形式回显发送到服务器的cookie,并添加两个新cookie:
public string GetData(int value)
{
var reply = string.Join(", ",
from x in HttpContext.Current.Request.Cookies.AllKeys
select x + "=" + HttpContext.Current.Request.Cookies[x].Value);
HttpContext.Current.Response.Cookies.Add(new HttpCookie("Test", "Test123"));
HttpContext.Current.Response.Cookies.Add(new HttpCookie("Test2", "Test1234"));
return reply;
}
以下测试程序为cookie创建CookieContainer,添加演示cookie,并为服务的端点注册新行为:
class Program
{
static void Main(string[] args)
{
var cookieCont = new CookieContainer();
using(var svc = new TestServiceReference.TestServiceClient())
{
cookieCont.Add(svc.Endpoint.Address.Uri, new Cookie("TestClientCookie", "Cookie Value 123"));
var behave = new CookieBehavior(cookieCont);
svc.Endpoint.EndpointBehaviors.Add(behave);
var data = svc.GetData(123);
Console.WriteLine(data);
Console.WriteLine("---");
foreach (Cookie x in cookieCont.GetCookies(svc.Endpoint.Address.Uri))
Console.WriteLine(x.Name + "=" + x.Value);
}
Console.ReadLine();
}
}
该行为用于添加自定义消息检查器并移交CookieContainer:
public class CookieBehavior : IEndpointBehavior
{
private CookieContainer cookieCont;
public CookieBehavior(CookieContainer cookieCont)
{
this.cookieCont = cookieCont;
}
public void AddBindingParameters(ServiceEndpoint serviceEndpoint,
System.ServiceModel.Channels
.BindingParameterCollection bindingParameters) { }
public void ApplyClientBehavior(ServiceEndpoint serviceEndpoint,
System.ServiceModel.Dispatcher.ClientRuntime behavior)
{
behavior.MessageInspectors.Add(new CookieMessageInspector(cookieCont));
}
public void ApplyDispatchBehavior(ServiceEndpoint serviceEndpoint,
System.ServiceModel.Dispatcher
.EndpointDispatcher endpointDispatcher) { }
public void Validate(ServiceEndpoint serviceEndpoint) { }
}
消息检查器在使用BeforeSendRequest
方法向服务器发送请求时添加cookie,并检索应在afterreceiverply
方法中更新的cookie。请注意,BeforeSendRequest
返回的correlationState
用于在afterreceiverply
中检索Uri:
public class CookieMessageInspector : IClientMessageInspector
{
private CookieContainer cookieCont;
public CookieMessageInspector(CookieContainer cookieCont)
{
this.cookieCont = cookieCont;
}
public void AfterReceiveReply(ref System.ServiceModel.Channels.Message reply,
object correlationState)
{
object obj;
if (reply.Properties.TryGetValue(HttpResponseMessageProperty.Name, out obj))
{
HttpResponseMessageProperty httpResponseMsg = obj as HttpResponseMessageProperty;
if (!string.IsNullOrEmpty(httpResponseMsg.Headers["Set-Cookie"]))
{
cookieCont.SetCookies((Uri)correlationState, httpResponseMsg.Headers["Set-Cookie"]);
}
}
}
public object BeforeSendRequest(ref System.ServiceModel.Channels.Message request,
System.ServiceModel.IClientChannel channel)
{
object obj;
if (request.Properties.TryGetValue(HttpRequestMessageProperty.Name, out obj))
{
HttpRequestMessageProperty httpRequestMsg = obj as HttpRequestMessageProperty;
SetRequestCookies(channel, httpRequestMsg);
}
else
{
var httpRequestMsg = new HttpRequestMessageProperty();
SetRequestCookies(channel, httpRequestMsg);
request.Properties.Add(HttpRequestMessageProperty.Name, httpRequestMsg);
}
return channel.RemoteAddress.Uri;
}
private void SetRequestCookies(System.ServiceModel.IClientChannel channel, HttpRequestMessageProperty httpRequestMessage)
{
httpRequestMessage.Headers["Cookie"] = cookieCont.GetCookieHeader(channel.RemoteAddress.Uri);
}
}
打开app.config文件并将allowCookies=“true”添加到绑定中 大概是这样的:
<binding allowCookies="true" />
@marc\s:即使是ASMX服务,他也应该使用“添加服务参考”。呃,不,你不需要。你认为你为什么这么做?同意,网络引用只是旧的迭代。使用上面@Markus的答案,而不是考虑到这里的头号悬赏赢家答案非常复杂,这似乎不太可能是答案,但至少对于eTapestry的API,它需要cookies来操作,这就是它所需要的。哇…旧答案,但完美。简单战胜了疯狂的复杂。我正在使用一个SOAP API(InsideSales),它需要一个登录名,为将来的所有调用设置一个会话cookie。这就是我所需要的。两个答案都是最好的。当您需要为在同一服务引用上执行的所有操作共享cookie时,此答案适用。但是,当你想在多个服务引用中共享一个cookie时,赢得赏金的答案就会出现。这肯定是正确的答案,但谷歌很容易忽视这一点。同样,对于关键字,如果您需要在.net应用程序的webservice中的windows应用程序中维护会话(相当于“在SoapUI中维护http会话”),只需输入此文件并将其粘贴到那里。没什么了:-)重要的是,如果设置了,这将不起作用!