还记得上篇文章中的PUT调用Rest服务的代码吗?不记得没关系,下面就是它的代码。
View Code
如果说每次调用服务都需要写这么多代码的话,那估计程序员会疯的。所以我决定对他进行包装。
在这段代码中有几个地方可以封装。
1:创建WebRequest的代码可以封装。
WebRequest webRequest =WebRequestCreator.ClientHttp.Create(
new Uri("http://localhost:19598/ProductService.svc/Product"));
webRequest.ContentType = "application/json";
webRequest.Method = "PUT";
2:序列化数据到requestStream对象中可以封装。
Stream requestStream = webRequest.EndGetRequestStream(requestAsyncCallback);
JsonObject jo = new JsonObject();
jo["Id"] = Guid.NewGuid().ToString();
jo["Name"] = "test";
string jsonString = jo.ToString();
byte[] buffer = System.Text.Encoding.Unicode.GetBytes(jsonString);
requestStream.Write(buffer, 0, buffer.Length);
requestStream.Close();
3:对返回结果执行的操作可以封装。
WebResponse webResponse = webRequest.EndGetResponse(responseAsyncCallback);
using (StreamReader reader = new StreamReader(webResponse.GetResponseStream()))
{
string result = reader.ReadToEnd();
//MessageBox.Show(result);
this.Dispatcher.BeginInvoke(() =>
{
MessageBox.Show(result);
});
}
按照1,2,3的方式我们先从1开始。代码如下:
1:使用GetWebRequest函数获取WebRequest对象,当然了你也可以用factory,但是在目前而言,一个函数就足够了。
/// <summary>
/// 获取WebRequest对象
/// </summary>
/// <param name="requestUriString">请求的地址</param>
/// <param name="httpMethod">请求的方法:GET,PUT,POST,DELETE</param>
/// <param name="contentType">请求的类型,json:"application/json"</param>
/// <returns></returns>
public static HttpWebRequest GetWebRequest(string requestUriString,
string httpMethod,
string contentType)
{
HttpWebRequest request = (HttpWebRequest)WebRequestCreator.ClientHttp.Create(new Uri(requestUriString));
request.Method = httpMethod;
if (!string.IsNullOrWhiteSpace(contentType))
{
request.ContentType = contentType;
}
return request;
}
2:封装序列化到RequestStream的过程。
Stream requestStream = webRequest.EndGetRequestStream(requestAsyncResult);
SerializeDataToRequestStream(data,requestStream);
requestStream.Close();
SerializeDataToRequestStream方法可以对JsonObject,匿名类,DataContract修饰的类进行序列化。
View Code
3:处理WebResponse。如果T是String类型则直接返回Json的string,否则使用DataContractJsonSerializer 反序列化成对象进行操作。
/// <summary>
/// 处理WebResponse
/// </summary>
/// <typeparam name="T">WebResponse返回结果的类型</typeparam>
/// <param name="webResponse">webResponse对象</param>
/// <param name="action">对结果的操作</param>
private static void HandleWebResponse<T>(WebResponse webResponse, Action<T> action)
{
using (Stream responseStream = webResponse.GetResponseStream())
{
DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(T));
if (typeof(T) == typeof(string))
{
T responseObject = (T)(object)GetStringFromStream(responseStream);
action(responseObject);
}
else
{
T responseObject = (T)serializer.ReadObject(responseStream);
action(responseObject);
}
}
}
好了,基本框架已经搭建好了,尝试下调用GET服务吧。
/// <summary>
/// 调用GET方法
/// </summary>
/// <typeparam name="T">结果的类型</typeparam>
/// <param name="requestUriString">请求的地址</param>
/// <param name="action">对结果的操作</param>
public static void InvokeGet<T>(string requestUriString, Action<T> action)
{
HttpWebRequest webRequest = GetWebRequest(requestUriString, "GET", string.Empty);
webRequest.BeginGetResponse((asyncResult) =>
{
WebResponse response = webRequest.EndGetResponse(asyncResult);
HandleWebResponse(response, action);
}, null);
}
调用GET服务比较简单,使用GET从指定的URL下载数据就可以了,那么调用POST,PUT,DELETE呢?
其实原理都比较简单,就是GetRequestStream--->写数据到RequestStream--->GetResponse。
所以可以写一个通用方法来调用PUT,POST,DELETE。
View Code
RestInvoker的完整代码如下:
View Code
但是我们还没有解决跨线程问题,还记得上篇文章中的this.Dispatcher.BeginInvoker吗?
但是在某些特定情况下,客户端不想调用BeginInvoker。
我们下回要修改RestInvoker,让它可以跨线程。 下回分解。。。
本文转自LoveJenny博客园博客,原文链接:http://www.cnblogs.com/LoveJenny/archive/2011/05/11/2041549.html,如需转载请自行联系原作者