我正在尝试为我的REST调用创建一个简单的类,所以我的应用程序中的多个位置都没有相同的代码。
问题是,我不知道如何从UploadStringCompleted()事件处理程序中通知一个调用UploadStringAsync()方法的对象。
这是我的班级,我添加了注释来标记我想要通知调用Post方法的对象的位置:
using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
namespace MyProject.Utils
{
public class Rest
{
private WebClient client = new WebClient();
private void Init()
{
client.UploadStringCompleted += new UploadStringCompletedEventHandler(client_UploadStringCompleted);
}
public void Post(string uri, string postRequest, object objectToNotify)
{
Init();
client.Headers["Content-Type"] = "application/x-www-form-urlencoded";
client.UploadStringAsync(new Uri(uri,
UriKind.RelativeOrAbsolute), "POST", postRequest, objectToNotify);
}
private void client_UploadStringCompleted(object sender,
UploadStringCompletedEventArgs e)
{
// here I would like to notify an object from
// which the Post() method has been called
// I don't know how to do this as this method has no idea
// which object called the method
// this doesn't work:
// (e.UserState.GetType())e.UserState.RestCallback(e);
}
}
}
编辑:
雅各布的建议之后修改了我的代码:
using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Browser;
namespace MyProject.Utils
{
public class Rest
{
private WebClient client = new WebClient();
private void Init()
{
client.UploadStringCompleted += new UploadStringCompletedEventHandler(client_UploadStringCompleted);
}
public void Post(
string uri, string postRequest,
Action<UploadStringCompletedEventArgs> callback)
{
HtmlPage.Window.Alert("bbb");
client.Headers["Content-Type"] = "application/x-www-form-urlencoded";
client.UploadStringAsync(new Uri(uri,
UriKind.RelativeOrAbsolute), "POST", postRequest, callback);
}
private void client_UploadStringCompleted(object sender,
UploadStringCompletedEventArgs result)
{
HtmlPage.Window.Alert("aaa");
var callback = (Action<UploadStringCompletedEventArgs>)result.UserState;
callback(result);
}
}
}
这就是我调用Post方法的方法:
string postRequest = "id=5":
Rest restClient = new Rest();
restClient.Post("http://mywebsite.com/", postRequest, RestCallback);
.......................
private void RestCallback(UploadStringCompletedEventArgs result)
{
if (result.Error != null)
{
ContactFormSuccess.Text = "There was an error sending email message.";
}
else
{
ContactFormSuccess.Text = "Email message successfully sent.";
}
}
答案 0 :(得分:2)
将需要通知的对象传递给Post()方法。然后,将该对象作为参数(使用其他重载之一)传递给UploadStringAsync()方法。然后,您的client_UploadStringCompleted可以使用事件参数信息来获取需要通知的对象。
答案 1 :(得分:2)
您可以修改Rest
类,以便为其提供回调委托而不是要通知的对象。它可能看起来像这样:
public void Post(
string uri, string postRequest,
Action<UploadStringCompletedEventArgs> callback)
{
Init();
client.Headers["Content-Type"] = "application/x-www-form-urlencoded";
client.UploadStringAsync(
new Uri(uri, UriKind.RelativeOrAbsolute),
"POST", postRequest, callback);
}
private void client_UploadStringCompleted(object sender,
UploadStringCompletedEventArgs e)
{
var callback = (Action<UploadStringCompletedEventArgs>)e.UserState;
callback(e);
}
然后,当您发出请求时,调用将如下所示:
var restClient = new Rest();
restClient.Post("http://your/url", "stuff", handleResult);
// ...
private void handleResult(UploadStringCompletedEventArgs result)
{
}
答案 2 :(得分:1)
根据John的建议,为什么不定义自己的界面,比如IDoSomethingAfterRest。在任何使用您的Rest类的对象上实现它。当Rest调用完成,并且控制在client_UploadStringCompleted函数中时,只需调用要执行的IDoSomethingAfterRest中的方法。
public interface IDoSomethingAfterPost
{
void DoSomethingAfterPost(<some parameters here>);
}
在正在调用Post的对象上实现接口:
public DoSomethingAfterPost(<some parameters here>)
{
Console.WriteLine("Just finished posting something");
}
现在,在您的Rest类中,当通知上传完成时,您可以在界面上回拨:
private void client_UploadStringCompleted(object sender,
UploadStringCompletedEventArgs e)
{
IDoSomethingAfterPost dsap = e.UserState as IDoSomethingAfterPost;
if (dsap != null)
{
_caller.DoSomethingAfterPost(e);
}
else
{
//Whoops! Someone needs to implement IDoSomethingAfterPost!
}
}
答案 3 :(得分:0)
client_UploadStringCompleted
是一种实例方法。您只需使用this
。
答案 4 :(得分:0)
如果它是一个Windows应用程序,你可以编写自己的事件,然后提高它,以便调用代码可以处理该事件。不确定它是否适用于Silvelight。