我有一个使用异步回调在WCF编写的服务器应用程序,以及ASP.NET中的webforms应用程序。 两个应用程序之间的所有通信都很好,我可以通过Web应用程序调用服务器中的公开函数,服务器可以将回调发送到Web应用程序,但有时回调中的函数可以工作,有时候,它们可以不。
例如,我想在Web应用程序上使用登录按钮向服务器发送用户名和密码,服务器对数据库进行检查,如果登录信息正确,则应发送回调,打开网络应用中的新页面。
以下是相关的服务器代码:
public void Login(String username, String password)
{
//DoCheckAgainstDatabase(username, password);
ICallback callback = OperationContext.Current.GetCallbackChannel<ICallback>();
callback.LoginSuccess();
}
和Web应用程序代码:
private InstanceContext _instanceContext;
private ServiceClient _service;
public CallbackHandler MyCallbackHandler = new CallbackHandler();
protected void Page_Load(object sender, EventArgs e)
{
_instanceContext = new InstanceContext(MyCallbackHandler);
_backEnd = new ServiceClient(_instanceContext, "NetTcpBinding_IAU", "net.tcp://localhost/MyService/Service");
_backEnd.Open();
MyCallbackHandler.LoginSucceeded += OnLoginSucceeded;
}
protected void LoginButton_Click(object sender, EventArgs e)
{
_backEnd.Login(UsernameTextBox.Text, PasswordTextBox.Text);
}
private void OnLoginSucceeded(object sender, EventArgs e)
{
ScriptManager.RegisterStartupScript(this.Page, Page.GetType(), "OpenClientWindow", "window.open('Client.aspx','_self');", true);
}
我可以放入断点,看到一切正常,只是代码'ScriptManager.RegisterStartupScript ...'不能一直正常执行。
这可能与线程有关吗?有人可以建议一种方法解决这个问题吗?
提前致谢! 大卫
答案 0 :(得分:0)
我认为你缺少脚本标签 - 用它包装你的window.open,比如
ScriptManager.RegisterStartupScript(this.Page, Page.GetType(), "OpenClientWindow", "<script>window.open('Client.aspx','_self');</script>", true);
答案 1 :(得分:0)
在我看来,你的页面生命周期可能会结束 - 或者至少进入Render阶段,这是启动脚本将被写入输出的地方 - 在调用回调之前。
是否可以同步调用您的服务,并且在服务调用返回之前不能继续LoginButton_Click
之外的其他服务?
答案 2 :(得分:0)
感谢Ann L.就此提供指导。我添加了一个ManualResetEvent,然后在按钮单击方法中,我等到收到回调,然后继续打开新页面:
private InstanceContext _instanceContext;
private ServiceClient _service;
public CallbackHandler MyCallbackHandler = new CallbackHandler();
private ManualResetEvent _resetEvent = new ManualResetEvent(false);
protected void Page_Load(object sender, EventArgs e)
{
_instanceContext = new InstanceContext(MyCallbackHandler);
_backEnd = new ServiceClient(_instanceContext, "NetTcpBinding_IAU", "net.tcp://localhost/MyService/Service");
_backEnd.Open();
MyCallbackHandler.LoginSucceeded += OnLoginSucceeded;
}
protected void LoginButton_Click(object sender, EventArgs e)
{
_backEnd.Login(UsernameTextBox.Text, PasswordTextBox.Text);
_resetEvent.WaitOne();
ScriptManager.RegisterStartupScript(this.Page, Page.GetType(), "OpenClientWindow", "window.open('Client.aspx','_self');", true);
}
private void OnLoginSucceeded(object sender, EventArgs e)
{
_resetEvent.Set();
}