Последующее решение для любого, кто может найти это в будущем.
Я попытался отправить запрос несколькими способами:
- Объекты сценария AJAX, созданные при добавлении службы WCF в качестве ServiceReference в ScriptManager. Итак, если класс службы WCF - это ProgressService с методом GetProgress, я создал новый объект ProgressService в JavaScript и назвал progressService.GetProgress ().
- Запрос XmlHttpRequest.
- Запрос jQuery $ .getJson ().
- Запрос Sys.Net.WebRequest.
- Запрос Sys.Net.WebServiceProxy.
Оказывается, что даже если клиентский запрос отправлен, т.е. не буферизован ASP.NET ScriptManager, служба WCF не будет отвечать, если она является частью того же веб-сайта в IIS.
Поэтому вместо того, чтобы создавать совершенно отдельный проект WCF и совершенно отдельный веб-сайт IIS, я переключился на традиционную веб-службу ASP.NET (SOAP) (.asmx).
Мне удалось сохранить часть службы .asmx того же проекта в Visual Studio и веб-сайт в IIS. Запрос отправляется во время обратной передачи, а служба отвечает во время обратной передачи.
После добавления его в качестве ServiceReference под ScriptManager я также смог по существу использовать те же самые объекты сценариев, создав новый ProgressWebService (), затем вызвав progressWebService.GetProgress (). Обработчик обратного вызова, переданный в GetProgress (), затем обрабатывает ответ и обновляет пользовательский интерфейс.
Веб-сервис:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Services;
using System.Web.Caching;
namespace MyNamespace
{
public class Progress
{
public string Message { get; set; }
public bool Complete { get; set; }
}
[WebService(Namespace = "MyNamespace")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
// To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line.
[System.Web.Script.Services.ScriptService]
public class ProgressWebService : System.Web.Services.WebService
{
protected static Dictionary<string, Progress> ProgressMessages = new Dictionary<string, Progress>();
[WebMethod]
public Progress GetProgress(string progressId)
{
return ProgressMessages.ContainsKey(progressId) ? ProgressMessages[progressId] : new Progress();
}
[WebMethod]
public void SetProgress(string progressId, string progress, bool complete)
{
if (ProgressMessages.ContainsKey(progressId))
{
ProgressMessages[progressId].Message = progress;
ProgressMessages[progressId].Complete = complete;
}
else
ProgressMessages.Add(progressId, new Progress() { Message = progress, Complete = complete });
}
[WebMethod]
public void SetProgressComplete(string progressId, bool complete)
{
if (ProgressMessages.ContainsKey(progressId))
ProgressMessages[progressId].Complete = complete;
else
ProgressMessages.Add(progressId, new Progress() { Complete = complete });
}
[WebMethod]
public void AddProgress(string progressId, string progress)
{
if (ProgressMessages.ContainsKey(progressId))
ProgressMessages[progressId].Message += progress;
else
ProgressMessages.Add(progressId, new Progress() { Message = progress });
}
}
}
Клиентская сторона:
<%@ Page language="c#" CodeFile="About.aspx.cs" Inherits="MyNamespace.About" %>
<%@ Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit" TagPrefix="ajaxToolkit" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<script type="text/javascript">
var ProgressServiceInterval; // global interval var, so it can be set and cleared across functions
function btnBackup_Click(sender, e) {
sender.disabled = true; // disable the backup button, so the request isn't duplicated
// start getting the backup progress from the web service
var progressService = new MyNamespace.ProgressWebService();
progressService.SetProgressComplete('<%= strBackupProgressGuid %>', false, null, null, null);
ProgressServiceInterval = setInterval('setBackupProgress()', 1000); // get progress once per second
}
function setBackupProgress() {
var progressService = new MyNamespace.ProgressWebService();
progressService.GetProgress('<%= strBackupProgressGuid %>', progressCallback, null, null);
}
function progressCallback(result) {
var txtBackupOutput = $get('<%= txtBackupOutput.ClientID %>');
try {
// show the progress message
txtBackupOutput.value = result.Message;
// stop checking if progress is complete
if (result.Complete == true) clearInterval(ProgressServiceInterval);
// scroll the textarea to the bottom
txtBackupOutput.scrollTop = txtBackupOutput.scrollHeight - txtBackupOutput.clientHeight;
} catch (ex) {
}
}
</script>
</head>
<body>
<form id="frmMyForm" method="post" runat="server">
<ajaxToolkit:ToolkitScriptManager runat="Server" EnablePartialRendering="true" EnablePageMethods="true" ID="ScriptManager1" >
<Services>
<asp:ServiceReference Path="ProgressWebService.asmx" />
</Services>
</ajaxToolkit:ToolkitScriptManager>
<asp:UpdatePanel ID="updBackup" runat="server" RenderMode="Inline">
<ContentTemplate>
<asp:UpdateProgress ID="updBackupProgress" AssociatedUpdatePanelID="updBackup" runat="server" DynamicLayout="false">
<ProgressTemplate>
<div style="text-align:center;margin-bottom:-32px;">
<img src="loading.gif" alt="Loading..." />
</div>
</ProgressTemplate>
</asp:UpdateProgress>
<asp:Button ID="btnBackup" runat="server" CssClass="SubmitButton" Text="Back Up Data" UseSubmitBehavior="false" OnClientClick="btnBackup_Click(this, event);" />
<br /><br />
<asp:TextBox ID="txtBackupOutput" runat="server" ReadOnly="true" TextMode="MultiLine" Rows="10" Width="100%" Wrap="true" />
</ContentTemplate>
</asp:UpdatePanel>
</form>
</body>
</html>
И на стороне сервера:
namespace MyNamespace
{
public partial class About
{
protected string strBackupProgressGuid
{
get
{
if (Session["strBackupProgressGuid"] == null)
Session["strBackupProgressGuid"] = Guid.NewGuid().ToString();
return Session["strBackupProgressGuid"] as string;
}
}
ProgressWebService _progressService;
protected ProgressWebService progressService
{
get
{
return _progressService = _progressService ?? new ProgressWebService();
}
}
void btnBackup_Click(object sender, EventArgs e)
{
progressService.SetProgress(strBackupProgressGuid, "Started\r\n", false);
System.Threading.Thread.Sleep(10000);
progressService.AddProgress(strBackupProgressGuid, "+10\r\n");
System.Threading.Thread.Sleep(10000);
progressService.AddProgress(strBackupProgressGuid, "+20\r\n");
System.Threading.Thread.Sleep(10000);
progressService.AddProgress(strBackupProgressGuid, "+30\r\n");
progressService.SetProgressComplete(strBackupProgressGuid, true);
}
}
}