我和我的工作夥伴花了很多時間找到答案,所以我想我應該分享這個自我回答的問題。如何啓用會話ASP.NET Web服務與不同域中的ajax客戶端一起工作?
我有一個Web服務(ASP.NET 4.5),需要使用會話狀態的方法。爲了存檔,我用EnableSession = true修飾了方法。這是MS建議在this article中做的事情(參見最後的「代碼塊A」)。
爲了讓Web服務能夠重新使用會話,它需要找到一個帶有會話ID的cookie。在第一次調用該方法時,該cookie在服務器端由Web服務器本身創建和設置。爲了在每次通話時重新發送該cookie,MS建議使用一個「cookie容器」,該cookie容器被分配給Web服務代理,保存在通話間並在每次通話時重複使用。 (請參閱最後的「代碼塊B」)。
只要您計劃從服務器端調用Web服務,它就會很好用。我需要使用jQuery ajax JSON Post調用從客戶端調用它(請參閱末尾的「代碼塊C」)。這段代碼很好用。事實上,具有會話ID的cookie會自動傳遞給Web服務。只要客戶端和Web服務位於同一個域中,就不需要Cookie罐。
如果客戶端與web服務(domainb.com)位於不同的域(domaina.com)中,則帶有會話標識的cookie根本不會傳遞。因此,每個對Web服務的調用都被認爲是第一個。
我在web配置中定義了以下頭文件以允許跨域調用。
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Headers" value="Content-Type" />
那麼,什麼是缺失?
代碼塊答:Web服務與裝飾方法
public class Util: WebService {
[ WebMethod(EnableSession=true)]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public int SessionHitCounter() {
if (Session["HitCounter"] == null) {
Session["HitCounter"] = 1;
}
else {
Session["HitCounter"] = ((int) Session["HitCounter"]) + 1;
}
return ((int) Session["HitCounter"]);
}
}
代碼塊B:服務器端餅乾罐解決方案
<script runat="server">
void EnterBtn_Click(Object Src, EventArgs E)
{
// Create a new instance of a proxy class for your XML Web service.
ServerUsage su = new ServerUsage();
CookieContainer cookieJar;
// Check to see if the cookies have already been saved for this session.
if (Session["CookieJar"] == null)
cookieJar= new CookieContainer();
else
cookieJar = (CookieContainer) Session["CookieJar"];
// Assign the CookieContainer to the proxy class.
su.CookieContainer = cookieJar;
// Invoke an XML Web service method that uses session state and thus cookies.
int count = su.PerSessionServiceUsage();
// Store the cookies received in the session state for future retrieval by this session.
Session["CookieJar"] = cookieJar;
// Populate the text box with the results from the call to the XML Web service method.
SessionCount.Text = count.ToString();
}
</script>
代碼塊C:AJAX調用
$.ajax({
type: "POST",
url: web_services_url + "/SessionHitCounter",
data: "{}",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (msg) {
alert(msg.d);
}
});