如何在ASP.NET Web窗体中使用流式文档打开新窗口

如何在ASP.NET Web窗体中使用流式文档打开新窗口,asp.net,webforms,Asp.net,Webforms,我有一个ASP.NET Web表单应用程序。我希望有一个按钮可以发回服务器,该服务器将使用我表单上的字段(验证后)作为服务器进程的参数,该服务器进程将生成文档并将其流回浏览器。我想用一些状态结果更新表单 实现这一目标的最佳方式是什么?现在,我点击按钮生成文档并将其流式传输回浏览器(这是一个Word文档,弹出对话框,Word文档可以成功打开),但页面没有更新 我的解决方案中有jQuery,因此如果需要的话,使用js不是问题。我在我的一台服务器上有一个非常类似的过程,我处理它的方式是在服务器上创建一

我有一个ASP.NET Web表单应用程序。我希望有一个按钮可以发回服务器,该服务器将使用我表单上的字段(验证后)作为服务器进程的参数,该服务器进程将生成文档并将其流回浏览器。我想用一些状态结果更新表单

实现这一目标的最佳方式是什么?现在,我点击按钮生成文档并将其流式传输回浏览器(这是一个Word文档,弹出对话框,Word文档可以成功打开),但页面没有更新


我的解决方案中有jQuery,因此如果需要的话,使用js不是问题。

我在我的一台服务器上有一个非常类似的过程,我处理它的方式是在服务器上创建一个临时文档,而不是进行实时流。它需要一些内务代码来整理它,但这确实意味着您可以返回生成的结果,然后在成功的情况下执行客户端重定向到生成的文档。在我的例子中,我使用jQuery和AJAX来生成文档和更新页面,但同样的原则也应该适用于纯WebForms方法。

这比我想象的要困难得多。主要问题是为Word文档打开新的浏览器窗口。窗口短暂闪烁,然后关闭-不显示Word文档。这似乎是一个安全问题

如果我点击页面上的一个按钮,我可以将单词doc作为响应流返回,浏览器对话框会弹出,允许我打开/保存/取消,但当然,我的页面不会刷新

我的最终解决方案是在单击按钮时使用客户端脚本,将表单的目标临时设置为_blank。这将强制对“单击回发”的响应转到新的浏览器窗口(在“下载”对话框关闭后自动关闭):

然后,我的OnTimeout函数重置表单的目标,然后开始轮询web服务以等待服务器进程完成。(我在会话中有一个计数器,一旦进程完成,我将更新该计数器。)

Poll函数只是使用jQuery的ajax函数来轮询我的web服务:

function Poll() {
    var currentCount = $("#hidCount").val();
    $.ajax({
        url: "/WebService1.asmx/CheckCount",
        data: JSON.stringify({ currentCount: currentCount }),
        success: function (data) {
            var changed = data.d;
            if (changed) {
                // Change recorded, so refresh the page.
                window.location = window.location;
            }
            else {
                // No change - check again in 1 second.
                setTimeout("Poll();", 1000);
            }
        }
    });
}
因此,这会对我的web服务进行1秒的轮询,等待会话计数器从页面上隐藏字段中的值更改。这意味着无论服务器进程需要多长时间来生成Word文档(以及更新数据库等),页面都不会刷新,直到完成为止

当web服务调用返回true时,页面将使用window.location=window.location语句刷新

为完整起见,我的Web服务如下所示:

/// <summary>
/// Summary description for WebService1
/// </summary>
[WebService(Namespace = "http://tempuri.org/")]
[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 WebService1 : WebService
{
    [WebMethod(EnableSession=true)]
    public bool CheckCount(int currentCount)
    {
        if (Session["Count"] == null)
            Session["Count"] = 0;
        var count = (int)Session["Count"];
        var changed = count != currentCount;

        return changed;
    }
}
//
///WebService 1的摘要说明
/// 
[WebService(命名空间=”http://tempuri.org/")]
[WebServiceBinding(ConformsTo=WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
//要允许使用ASP.NET AJAX从脚本调用此Web服务,请取消注释以下行。
[System.Web.Script.Services.ScriptService]
公共类WebService 1:WebService
{
[WebMethod(EnableSession=true)]
公共布尔校验计数(int currentCount)
{
if(会话[“计数”]==null)
会话[“计数”]=0;
变量计数=(int)会话[“计数”];
变量更改=计数!=当前计数;
回报发生变化;
}
}
希望这能帮助别人

function OnTimeout() {
    // Reset the form's target back to this page (from _blank).
    form1.target = '_self';

    // Poll for a change.
    Poll();
}
function Poll() {
    var currentCount = $("#hidCount").val();
    $.ajax({
        url: "/WebService1.asmx/CheckCount",
        data: JSON.stringify({ currentCount: currentCount }),
        success: function (data) {
            var changed = data.d;
            if (changed) {
                // Change recorded, so refresh the page.
                window.location = window.location;
            }
            else {
                // No change - check again in 1 second.
                setTimeout("Poll();", 1000);
            }
        }
    });
}
/// <summary>
/// Summary description for WebService1
/// </summary>
[WebService(Namespace = "http://tempuri.org/")]
[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 WebService1 : WebService
{
    [WebMethod(EnableSession=true)]
    public bool CheckCount(int currentCount)
    {
        if (Session["Count"] == null)
            Session["Count"] = 0;
        var count = (int)Session["Count"];
        var changed = count != currentCount;

        return changed;
    }
}