对REST架构 风格下WCF的一点补充
这几天思考REST 架构下POST复杂数据类型的问题查了写资料,以及通过与WCF 大牛------Frank Xulei进行了一番交流对REST有了一些进一步的认识。本篇作为:1、REST与SOA两种架构下WCF的异同比较 2、通过HTTP协议标准动作使用REST WCF 服务 这两篇的一个补充。
起因是这样的:在SOA架构下,一般都是通过定义服务契约的方式最终通过WSDL将元数据对外发布,以供调用者使用。也就是说在SOA中,通过服务契约定义向外公布服务对外提供的操作。如果先学习SOA,然后接触REST,可能会在使用REST的时候会沿用SOA下的一些习惯。我在进行REST架构下的WCF学习过程中也是沿用了这一思路:先定义服务接口,然后实现服务供消费者使用。
后来仔细想了想REST架构的原则,通过定义契约接口的方式固然可行,并且在前几节中也做了实现的说明。但真的有必要这样做吗。?
由于REST架构下的服务通过公共的连接器接口(主要是指GET,POST,PUT,DELETE)对服务进行访问。客户端只需知道服务的统一资源标识---URI(Uniform Resources Identifier)以及相应的HTTP动作就行了(可以通过REST 架构下的帮助页面,即HTTP://ServiceAddress/help就能知道各个服务如何使用)。因此在REST架构下,WCF服务无需向客户端暴露元数据信息。这也是REST架构下,WCF不需要定义服务契约的原因。由于没有元数据信息,因此REST WCF服务也不能通过添加引用的方式使用。
小结:
1、REST 架构下无需给服务定义服务契约(非必须,若定义也行)。
2、REST 架构下的服务不能添加引用的方式使用。
在面向对象语言中,操作一般都针对对象而言。REST中如何POST自定义类型。?下面说说REST架构下,复杂数据类型的POST操作。(代码下载)
服务的实现:
[OperationContract]
[WebInvoke(UriTemplate = "Person/Post")]
public string Post(Person person)
{
return person.Name + person.Tel;
}
调用方式如下:
static void InvokeMutiType()
{
using (MemoryStream ms = new MemoryStream())
{
WebClient webClient = new WebClient();
Person person = new Person { Name = "tyb", Tel = "01021234568" };
XmlSerializer xmlSerializer = new XmlSerializer(typeof(Person));
xmlSerializer.Serialize(ms, person);
ms.Seek(0, SeekOrigin.Begin);
XmlDocument xmlDocument = new XmlDocument();
xmlDocument.Load(ms);
webClient.Headers[HttpRequestHeader.ContentType] = "application/xml";
try
{
string str = webClient.UploadString("http://localhost:6012/RestService.svc/Person/Post", "POST" , xmlDocument.InnerXml);
Console.WriteLine("接收到的数据为:{0}", str);
}
catch (WebException exception)
{
Console.WriteLine(exception.Status);
}
}
}
调用结果如下图:
由上可知:对自定义类型数据采用POST操作时,需要通过序列话然后发送给服务端。服务端在接受到数据后能自动映射到自定义类型上。
以上通过WebClient发送的,也可以通过HttpWebRequest与HttpWebResponse来实现。