在使用asp.net编写webservice时,默认情况下是不支持session的,但我们可以把WebMethod的EnableSession选项设为true来显式的打开它,请看以下例子:
1 新建网站WebSite
2 新建web服务WebService.asmx,它具有以下两个方法:
C#-Code:
[WebMethod(EnableSession = true)]
public string Login(string name)
{
Context.Session["name"] = name;
return name;
}
[WebMethod(EnableSession = true)]
public string GetName()
{
if (Context.Session["name"] != null)
return Context.Session["name"].ToString();
else
return "";
}
3 添加asp.net页面SessionInWebservice.aspx
ASP.NET-Code:
<form id="form1" runat="server">
<div>
<asp:TextBox ID="txtName" runat="server"></asp:TextBox>
<asp:Button ID="btnLogin" runat="server"
Text="Login" OnClick="btnLogin_Click" />
</div>
<div>
<asp:Button ID="btnGetName" runat="server"
Text="GetName" OnClick="btnGetName_Click" />
<asp:Label ID="lblName" runat="server" Text="Label"></asp:Label>
</div>
</form>
SessionInWebservice.aspx.cs
C#-Code:
protected void btnLogin_Click(object sender, EventArgs e)
{
WebService ws = new WebService();
ws.Login(txtName.Text);
}
protected void btnGetName_Click(object sender, EventArgs e)
{
WebService ws = new WebService();
lblName.Text = ws.GetName();
}
问题似乎到此结束了,按Login按钮记录用户名以后,再按GetName就可以获取到刚才输入的名字。
但如果我们另外新建一个website,并添加web引用来调用刚才编写的webservice,问题就出来了,GeName方法并没有获取到我们刚才登录的用户名(如果是在winform中调用该方法,也会出现同样的问题)。莫非这个方法行不通了?
其实不然,我们给该WebService的CookieContainer赋值就可以了,修改SessionInWebservice.aspx.cs 的代码:
C#-Code:
private static System.Net.CookieContainer cookieContainer
= new System.Net.CookieContainer();
protected void btnLogin_Click(object sender, EventArgs e)
{
localhost.WebService ws = new localhost.WebService();
ws.CookieContainer = cookieContainer;
ws.Login(txtName.Text);
}
protected void btnGetName_Click(object sender, EventArgs e)
{
localhost.WebService ws = new localhost.WebService();
ws.CookieContainer = cookieContainer;
lblName.Text = ws.GetName();
}
请注意:Login方法和GetName方法必须指定同一个CookieContainer,因此在这里我们使用了静态变量。
但如果是在不同的页面中调用该webservice,问题依旧存在,因此我们需要重新修改代码,通过编写新类继承上面的webservice,并给CookieContainer赋值就可以解决该问题了:
C#-Code:
public class WebService1:localhost.WebService
{
private static System.Net.CookieContainer cookieContainer;
static WebService1()
{
cookieContainer = new System.Net.CookieContainer();
}
public WebService1()
{
this.CookieContainer = cookieContainer;
}
}
调用的时候也不需要重新给CookieContainer赋值了:
C#-Code:
protected void btnLogin_Click(object sender, EventArgs e)
{
WebService1 ws = new WebService1();
ws.Login(txtName.Text);
}
protected void btnGetName_Click(object sender, EventArgs e)
{
WebService1 ws = new WebService1();
lblName.Text = ws.GetName();
}
I’ve come across a number of developers who have run into this issue when trying to call a web service in Visual Studio 2005 Beta 2. The symptom of the problem is that when trying to call a web service that is running on the "ASP.NET Development Server" from another application, the web service throws a WebException with the message: “The request failed with HTTP status 401: Unauthorized.”
First and foremost, this issue is not related to debugging. If you run the application outside of Visual Studio, you’ll see the same result. Also noteworthy to mention is that when you run the web service by itself, everything works fine. It’s only when you call the web service from another application that it fails.
Why do I get this error?
The reason for this error is that by default, a web service project in Visual Studio 2005 Beta 2 required NTLM authentication. When you call the web service from another application, the application tries to call into the web service with anonymous access and fails. But, when you call the web service from the web service test page in Internet Explorer, your credentials are passed from IE to the web service which means that the call succeeds.
How do I fix this error?
There are two ways to fix this error.1. Disable NTLM Authentication in Project Properties
If your web service is not intended to require authentication, the easiest way to fix this error is to turn off NTML authentication in a web service project. To do this, right click on the web service project and select “Property Pages”. On the “Start Options” page, uncheck “NTLM Authentication”. NOTE: disabling this option has security implications if you are running the web service in a Terminal Server environment. If the web service is on your local machine and it’s not being used in a Terminal Server environment, then you should be fine.
2. Pass User's Credentials from Calling Application to Web Service
If your web service is intended to require authentication and not anonymous access, then pass the credentials of the user from the application to the web service. Here is an example:
Samples.TimeWebService ws = new Samples.TimeWebService();
ws.Credentials = System.Net.CredentialCache.DefaultCredentials;
string currentTime = ws.GetCurrentTime();