• 目的

使用Wcf(C#)搭建一个Restful Service

  • 背景

最近接到一个项目,客户要求使用Restful 方式接收到数据,并对数据提供对数据的统计显示功能,简单是简单,但必须要使用Restful方式,客户端传递数据就必须使用Rest ful的格式的url,提交方式为Post。

其实在之前的公司里边就开发过一个restful服务,但只记得自己使用的wcf,而今已经忘记的差不多了,还以为只是简单的搭建一个wcf就可以,今天起初就创建了一个wcf项目,发现wcf项目http://localhost:6001/Test.svc好像很让人纠结就是这个url就是多出一个。svc,wsd什么之类的,根本就不是restful,后来上网上搜到原来我们之前不是用的简单的wcf工程,而是通过Wcf rest service template工程创建的。

  • 创建Wcf rest service template工程:

在vs 新建工程-》online templates-》在搜索框中输入Wcf rest service template-》

创建好工程的工程:

  • 这个工程值得注意的有以下地方:

1, Gobal.asax文件中的代码:

  public class Global : HttpApplication
{
void Application_Start(object sender, EventArgs e)
{
RegisterRoutes();
} private void RegisterRoutes()
{
// Edit the base address of Service1 by replacing the "Service1" string below
RouteTable.Routes.Add(new ServiceRoute("Service1", new WebServiceHostFactory(), typeof(Service1)));
}
}

这里边是注册了url访问 route,这个访问格式就包含一下集中restful访问类型:

2.访问方式

备注:我默认的url host url为:http://localhost:6001/

访问url:http://localhost:6001/Service1           提交方式:GET      调用函数为:GetCollection

访问url:http://localhost:6001/Service1           提交方式:POST    调用函数为:Create

访问url:http://localhost:6001/Service1/1        提交方式:Get       调用函数为:Get(...)

访问url:http://localhost:6001/Service1/1        提交方式:PUT       调用函数为:Update(...)

访问url:http://localhost:6001/Service1/1        提交方式:PUT       调用函数为:Delete(...)
3.怎么注册访问方式

[WebGet(UriTemplate = "")]

List<SampleItem> GetCollection()

[WebInvoke(UriTemplate = "", Method = "POST")]
SampleItem Create(SampleItem instance)

[WebGet(UriTemplate = "{id}")]
SampleItem Get(string id)

[WebInvoke(UriTemplate = "{id}", Method = "PUT")]
SampleItem Update(string id, SampleItem instance)

[WebInvoke(UriTemplate = "{id}", Method = "DELETE")]
void Delete(string id)

其实我们可以注意到这些"访问url"访问到的“调用的函数”上的注解:

指定了访问url为:http://localhost:6001/Service1

WebGetAttribute

a. 决定了提交方式为Get,

b. UriTemplate ,决定了是否在http://localhost:6001/Service1后边追加其他路径

c. 其他参数RequestFormat = WebMessageFormat.Xml, ResponseFormat = WebMessageFormat.Json等

WebInvokeAttribute

a.UriTemplate ,决定了是否在http://localhost:6001/Service1后边追加其他路径

b.Method,决定了提交方式,可选参数包含Get,Post,Put,Delete,当然也支持Header等其他方式。

c. 其他参数RequestFormat = WebMessageFormat.Xml, ResponseFormat = WebMessageFormat.Json等

  • 关于请求、返回数据格式

REST被受到欢迎原因:

1,分布式架构

2,请求、返回格式支持xml,json。

3,支持异步请求/提交数据,这使得Javascript可以轻松调用RESTful服务。

A.如果手动配置请求、返回数据格式?

wcf rest service template内置了简单的注册方式:在上边我们提到的WebGetAttribute,WebInvokerAttribute中都支持参数RequestFormat,ResponseFormat,可以手动的在代码中制定他们的参数类型:

  // Summary:
// An enumeration that specifies the format of Web messages.
public enum WebMessageFormat
{
// Summary:
// The XML format.
Xml = ,
//
// Summary:
// The JavaScript Object Notation (JSON) format.
Json = ,
}

B.如果动态配置请求、返回数据格式?

相比手动配置之下,动态选择格式还是更灵活。打开之前创建的项目,在web.config中,设置:

<standardEndpoint name="" helpEnabled="true" automaticFormatSelectionEnabled="true"/>

将automaticFormatSelectionEnabled设置为true

设置后,我们就可以通过url访问到当前我们可以访问的路径接口等.

  • 测试客户端

比如我们Restful Service代码如下:

  [WebInvoke(UriTemplate = "Servlet", Method = "POST", ResponseFormat = WebMessageFormat.Json)]
public string Welcome()
{
try
{
// 接收传递的参数信息
string param= HttpContext.Current.Request["param"]; // do somthing // 返回成功操作状态信息
return "{\"status\": 0, \"msg\": \"操作成功!\"}"; }
catch (Exception ex)
{ // 返回失败操作状态信息
return "{\"status\": 1, \"msg\": \"操作失败!\"}"; ;
}
}

客户端调试:

static void Main(string[] args)
{
NameValueCollection responseEntity = new NameValueCollection();
responseEntity.Add("param", ""); string baseUrl = "http://localhost:6001/TestReceiver/Welcome"; try
{
WebClient webClient = new WebClient(); // 采取POST方式必须加的header,如果改为GET方式的话就去掉这句话即可
webClient.Headers.Add("Content-Type", "application/x-www-form-urlencoded"); // 得到返回字符流 
byte[] responseData = webClient.UploadValues(baseUrl, "POST", responseEntity); // 解码返回值 
string byRemoteInfo = Encoding.UTF8.GetString(responseData); Console.WriteLine(byRemoteInfo); }
catch (Exception ex)
{
Console.WriteLine(ex.Message);
Console.WriteLine(ex.StackTrace);
} Console.ReadKey();
}

  上边我们采用的接收参数的方式是HttpContext.Current.Request.Params["param"]的方式来接收参数,确切说,这种方式在vs的调试模式下是可以接收到参数的,但是在iis上就不是这么好说了(具体问题,我不是太清楚是不是因为我的服务器上没有注册WCF组建的方式(验证方案参考:http://blog.csdn.net/findsafety/article/details/9045721),还是其他问题;具体原因我暂时不能去确认,服务器远程不了,只能明天去确认)。

  • 服务器端在函数的参数中写入要接收的参数信息,作为函数的参数,这种方式是可行的。

  demo:

  

 public class Global : HttpApplication
{
void Application_Start(object sender, EventArgs e)
{
RegisterRoutes();
} private void RegisterRoutes()
{
// Edit the base address of Service1 by replacing the "Test" string below
RouteTable.Routes.Add(new ServiceRoute("Test", new WebServiceHostFactory(), typeof(Test)));
}
} [ServiceContract]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
// NOTE: If the service is renamed, remember to update the global.asax.cs file
public class Test
{
private Logger logger = LogManager.GetCurrentClassLogger(); [WebInvoke(UriTemplate = "Login", Method = "POST", BodyStyle = WebMessageBodyStyle.WrappedRequest)]
public bool Login(string userName, string userPassword)
{
//模拟登录,实际使用时需数据库访问
if (userName == "huangbo" && userPassword == "")
{
return true;
}
return false;
}
} public class UserInfo
{
public string userName { get; set; }
public string userPassword { get; set; }
} class Program
{
static void Main(string[] args)
{
string baseUrl = "http://localhost:6001/Test/Login"; UserInfo info = new UserInfo
{
userName = "",
userPassword = ""
}; //先访问LoginService,得到授权
var request = (HttpWebRequest)WebRequest.Create(baseUrl);
request.ContentType = "application/json;charset=utf-8";
request.Method = "POST";
request.KeepAlive = true;
//request.ClientCertificates.Add(cert);
//使用JSON.NET将对象序列化成JSON字符串
var requestBody = Newtonsoft.Json.JsonConvert.SerializeObject(info);
byte[] databytes = Encoding.UTF8.GetBytes(requestBody);
request.ContentLength = databytes.Length;
using (var writer = request.GetRequestStream())
{
writer.Write(databytes, , databytes.Length);
}
var response = request.GetResponse();
using (var stream = response.GetResponseStream())
{
using (var reader = new StreamReader(stream))
{
Console.WriteLine(reader.ReadToEnd());
}
}
}
}

参考资料:

http://www.cnblogs.com/xiarifeixue/archive/2011/04/27/restful.html

http://www.cnblogs.com/bearhb/archive/2012/07/11/2586412.html

怎么接收参数:

UserInfo info = new UserInfo
{
userName = “user”,
userPassword = “pwd”
};

string strJson=Newtonsoft.Json.JsonConvert.SerializeObject(message);

byte[] jsonBytes=Encoding.UTF8.GetBytes(strJson);

test client post method: json string UploadData(string url,string method,byte[] bytes);

webClient.UploadData("url","Post",jsonBytes);

mapping WCF Rest Service method:

[WebInvoke(UriTemplate = "", Method = "POST",BodyStyle=WebMessageBodyStyle.WrappedRequest)]

 public bool Login(string userName, string userPassword)
{
  return true;
}

Wcf Restful Service服务搭建的更多相关文章

  1. 构建基于WCF Restful Service的服务

    前言 传统的Asmx服务,由于遵循SOAP协议,所以返回内容以xml方式组织.并且客户端需要添加服务端引用才能使用(虽然看到网络上已经提供了这方面的Dynamic Proxy,但是没有这种方式简便), ...

  2. WCF Restful Service的服务

    构建基于WCF Restful Service的服务 前言 传统的Asmx服务,由于遵循SOAP协议,所以返回内容以xml方式组织.并且客户端需要添加服务端引用才能使用(虽然看到网络上已经提供了这方面 ...

  3. [转]构建基于WCF Restful Service的服务

    本文转自:http://www.cnblogs.com/scy251147/p/3566638.html 前言 传统的Asmx服务,由于遵循SOAP协议,所以返回内容以xml方式组织.并且客户端需要添 ...

  4. WCF Restful Service

    对 Web Services.WCF 和 Restful 的扫盲可参见:https://www.cnblogs.com/scy251147/p/3382436.html 关于之前对 WCF 的学习,可 ...

  5. WCF Restful Service Get / Post请求

    Rest 它是用于创建分布式超文本媒体的一种架构方式,我们可以通过标准的HTTP(GET,POST,PUT,DELETE)操作来构建基于面向资源的软件架构方式(Resource-Oriented Ar ...

  6. [转]WCF RESTful service and WebGrid in ASP.NET MVC 5

    使用WebClient调用WCF服务 流程:从View获取实体类-->序列化-->写入内存流中-->传给远端的WCF服务 Get.POST.PUT.DELETE,客户端以流的方式调用 ...

  7. 在IIS8.5的环境下配置WCF的Restful Service

    今天在客户的环境中(Windows Server 2012 R2 + IIS 8.5)搭建Call WCF Restful Service的功能,发现了几个环境配置的问题,记录如下: 1):此环境先安 ...

  8. [经验] - JQuery.Ajax + 跨域 (crossDomain) + POST + JSON + WCF RESTful, 5大陷阱和解决方案

    最近在开发WSS RESTful服务的时候, 碰到了这些个纠结的问题. 在网上查找了半天, 找到n多种解决方案, 但是都是部分的, 要么是没有跨域的情况, 要么是没有post的情况, 要么不是用WCF ...

  9. JQuery.Ajax + 跨域 (crossDomain) + POST + JSON + WCF RESTful, 5大陷阱和解决方案

    JQuery.Ajax + 跨域 (crossDomain) + POST + JSON + WCF RESTful, 5大陷阱和解决方案 最近在开发WSS RESTful服务的时候, 碰到了这些个纠 ...

随机推荐

  1. Yii源码阅读笔记(七)

    接上次的组件(component)代码: /** * Returns a list of behaviors that this component should behave as. * 定义该对象 ...

  2. 【转载】loadrunner使用system()函数调用Tesseract-OCR识别验证码遇到的问题

    俗话说前人栽树,后人乘凉,此话一点不假,结合云层的一遍文章:http://bbs.51testing.com/thread-533920-1-1.html,知道还有一个Tesseract-OCR可以用 ...

  3. 使用 Linux 搭建 VPN

    http://blog.csdn.net/catoop/article/details/7537012 VPN服务器的配置与应用 实验场景 通过将Linux配置VPN服务器允许远程计算机能够访问内网. ...

  4. Python实用工具包Scrapy安装教程

       对于想用每个想用Python开发网络爬虫的开发者来说,Scrapy无疑是一个极好的开源工具.今天安装之后觉得Scrapy的安装确实不易啊.所以在此博文一篇,往后来着少走弯路. 废话不多说了,如果 ...

  5. Oracle存储过程基本语法 存储过程

    Oracle存储过程基本语法 存储过程 1 CREATE OR REPLACE PROCEDURE 存储过程名 2 IS 3 BEGIN 4 NULL; 5 END; 行1: CREATE OR RE ...

  6. jboss4.2.3建立oracle JMS应用

    一.基本配置 1 增加oracle驱动文件,ojdbc6.jar,不能使用小于该版本的jdbc驱动,jboss-4.2.3.GA\server\default\lib 2 增加retrotransla ...

  7. 浅谈 举家搬迁静态文件到CDN

    由于七牛CDN最近做活动,对于标准用户可以免费使用如下优惠 10 GB 存储空间 10 G/月 下载流量 10 万次/月 PUT/DELETE 请求 100 万次/月 GET 请求 以上这些指标直接就 ...

  8. nrf51822裸机教程-RTC

    RTC0被协议栈使用了.所以在跑蓝牙程序的情况下.RTC0不能使用. RTC相关寄存器如下: EVTEN,EVTENSET,EVTENCLR. 这三个寄存器用来设置是否使能某个事件.(TICK,OVR ...

  9. Java程序设计的基本原则

    Java程序设计的基本原则-1 1.面向对象 这是java编程里面大家公认的第一原则 2.优先使用对象组合而非类继承 3.分层 最典型的三层架构,表现层-->逻辑层-->数据层 表现层功能 ...

  10. FastMM、FastCode、FastMove的使用(图文并茂)

    FastMM是一个替换Embarcadero Delphi Win32应用程序的快速内存管理器,以及可以在多线程下使用,不容易产生内存碎片,并且无需使用外部DLL文件就可以支持共享内存. 使用方法:1 ...