wcf Rest 服务宿主在windows服务及客户端访问

首先写好服务,代码如下:

wcf Rest 服务宿主在windows服务及客户端访问
 1 using System;
 2 using System.Collections.Generic;
 3 using System.Runtime.Serialization;
 4 using System.ServiceModel.Web;
 5 using System.ServiceModel;
 6 
 7 
 8 namespace Artech.WcfServices.Service
 9 {
10     [ServiceContract(Namespace = "Artech.WcfServices.Service")]
11     public interface IEmployees
12     {
13         [OperationContract]
14         [WebGet(UriTemplate = "all", ResponseFormat = WebMessageFormat.Json)]
15         IEnumerable<Employee> GetAll();
16 
17         [OperationContract]
18         [WebGet(UriTemplate = "{id}")]
19         Employee Get(string id);
20 
21         [OperationContract]
22         [WebInvoke(UriTemplate = "/", Method = "POST", RequestFormat=WebMessageFormat.Json)]
23         void Create(Employee employee);
24 
25         [OperationContract]
26         [WebInvoke(UriTemplate = "/Add", Method = "POST", RequestFormat = WebMessageFormat.Json)]
27         void Add(string employee);
28 
29         [OperationContract]
30         [WebInvoke(UriTemplate = "/", Method = "PUT")]
31         void Update(Employee employee);
32 
33         [OperationContract]
34         [WebInvoke(UriTemplate = "{id}", Method = "DELETE")]
35         void Delete(string id);
36     }
37 
38     [DataContract(Namespace = "Artech.WcfServices.Service")]
39     public class Employee
40     {
41         [DataMember]
42         public int Id { get; set; }
43         [DataMember]
44         public string Name { get; set; }
45         [DataMember]
46         public string Department { get; set; }
47         [DataMember]
48         public string Grade { get; set; }
49         [DataMember]
50         public bool IsHire { get; set; }
51         [DataMember]
52         public DateTime EntryDate { get; set; }
53     }
54 }
IEmployee接口和Employee实体类

 服务实现类:

wcf Rest 服务宿主在windows服务及客户端访问
 1 using System;
 2 using System.Collections.Generic;
 3 using System.IO;
 4 using System.Linq;
 5 using System.Reflection;
 6 using System.Runtime.Serialization.Json;
 7 using System.Text;
 8 using System.ServiceModel.Web;
 9 using System.Net;
10 
11 namespace Artech.WcfServices.Service
12 {
13 public class EmployeesService : IEmployees
14 {
15     private log4net.ILog logger = log4net.LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
16     private static List<Employee> employees = new List<Employee>
17     {
18         new Employee{ Id = 1 ,Name="张三", Department="开发部", Grade = "G7",EntryDate =Convert.ToDateTime("2013/07/08"),IsHire =true},    
19         new Employee{ Id = 2, Name="李四", Department="人事部", Grade = "G6",EntryDate= Convert.ToDateTime("2014/03/11"),IsHire =false},
20         new Employee{ Id = 3, Name="王五", Department="销售部", Grade = "G8",EntryDate =Convert.ToDateTime("2010/12/10"),IsHire =true}
21     };
22     public Employee Get(string id)
23     {
24         Employee employee = employees.FirstOrDefault(e => e.Id == int.Parse(id));
25         if (null == employee)
26         {
27             WebOperationContext.Current.OutgoingResponse.StatusCode = HttpStatusCode.NotFound;
28         }
29         return employee;
30     }
31     public void Create(Employee employee)
32     {
33         employees.Add(employee);
34     }
35     private void W(string msg)
36     {
37         var sr=new StreamWriter("C:/1.txt",true);
38         sr.Write(msg);
39         sr.Write("\r\n");
40         sr.Close();
41         sr.Dispose();
42     }
43     public void Add(string employee)
44     {
45         
46         W(employee);
47         try
48         {
49             Employee emp = Deserialize<Employee>(employee);
50 
51             employees.Add(emp);
52         }
53         catch (Exception ex)
54         {
55             W(ex.ToString());
56         }
57         
58     }
59 
60     public void Update(Employee employee)
61     {
62        // var emp = JsonConvert.DeserializeObject<Employee>(employee);
63         this.Delete(employee.Id.ToString());
64         employees.Add(employee);
65     }
66     public void Delete(string id)
67     {
68         Employee employee = this.Get(id);
69         if (null != employee)
70         {
71             employees.Remove(employee);
72         }
73     }
74     public IEnumerable<Employee> GetAll()
75     {
76         return employees;
77     }
78     public static T Deserialize<T>(string json)
79     {
80         var jsondata = Encoding.UTF8.GetBytes(json);
81         var obj = Activator.CreateInstance<T>();
82         using (var ms = new MemoryStream(jsondata))
83         {
84             var serializer = new DataContractJsonSerializer(obj.GetType());
85             return (T)serializer.ReadObject(ms);
86         }
87     }
88 
89 }
90 }
EmployeeService服务实现类

 还可以定义更多的服务,如MicroblogService、UserService等,和EmployeeService一样,代码略过。

然后让它们寄宿在windows service应用程序上,如下:

新建一个项目,名称为WindowsServiceDemo,写app.config配置文件:

wcf Rest 服务宿主在windows服务及客户端访问
 1 <?xml version="1.0" encoding="utf-8" ?>
 2 <configuration>
 3   
 4   <configSections>
 5     <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net-net-1.0" />
 6   </configSections>
 7 
 8 
 9   <log4net>
10     <root>
11       <level value="ALL" />
12       <appender-ref ref="LogFileAppender" />
13     </root>
14 
15     <appender name="LogFileAppender"  type="log4net.Appender.FileAppender" >
16       <param name="File" value="Log\log-file.txt" />       
17       <param name="AppendToFile" value="true" />
18       <layout type="log4net.Layout.PatternLayout">
19         <param name="ConversionPattern"  value="记录时间:%d     线程 ID:[%t]    日志级别:%-5p     出错类:%logger property:[%property{NDC}]     错误描述:%m%n" />
20       </layout>
21     </appender>
22   </log4net>
23   <system.serviceModel>
24        <services>
25       <service name="WcfRestServiceLibrary.Service.MicroblogService" behaviorConfiguration="MicroblogServiceBehavior">
26         <host>
27           <baseAddresses>
28             <add baseAddress="http://localhost:8033/MicroblogService"/>
29           </baseAddresses>
30         </host>
31         <endpoint address="http://localhost:8033/MicroblogService"
32                    binding ="webHttpBinding" 
33                   contract="WcfRestServiceLibrary.Service.IMicroblogService"  behaviorConfiguration="web"/>
34       </service>
35       <service name="Artech.WcfServices.Service.EmployeesService" behaviorConfiguration="EmployeesServiceBehavior">
36         <host>
37           <baseAddresses>
38             <add baseAddress="http://localhost:3723/EmployeesService"/>
39           </baseAddresses>
40         </host>
41         <endpoint address="http://localhost:3723/EmployeesService"
42                    binding ="webHttpBinding"
43                   contract="Artech.WcfServices.Service.IEmployees" behaviorConfiguration="web"/>
44       </service>
45       <service name="WcfRestServiceLibrary.UserService.UserService" behaviorConfiguration="UserServiceBehavior">
46         <host>
47           <baseAddresses>
48             <add baseAddress="http://localhost:7033/UserService"/>
49           </baseAddresses>
50         </host>
51         <endpoint address="http://localhost:7033/UserService"
52                   binding ="webHttpBinding"
53                   contract="WcfRestServiceLibrary.UserService.IUserService"  behaviorConfiguration="web"/>
54         <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
55       </service>
56       <service name="wcfServiceLib.Service1" behaviorConfiguration="Service1Behavior">
57         <host>
58           <baseAddresses>
59             <add baseAddress="http://localhost:6033/Service1"/>
60           </baseAddresses>
61         </host>
62         <endpoint address="http://localhost:6033/Service1"
63                   binding ="webHttpBinding"
64                   contract="wcfServiceLib.IService1"  behaviorConfiguration="web"/>
65       </service>
66     </services>
67     
68     <behaviors>
69       <serviceBehaviors>
70         <behavior name="MicroblogServiceBehavior" >
71           <serviceMetadata httpGetEnabled="true" httpGetUrl="http://localhost:8033/MicroblogService/MetaData"/>
72         </behavior>
73         <behavior name="EmployeesServiceBehavior" >
74           <serviceMetadata httpGetEnabled="true" httpGetUrl="http://localhost:3723/EmployeesService/MetaData"/>
75         </behavior>
76         <behavior name="UserServiceBehavior" >
77           <serviceMetadata httpGetEnabled="true" httpGetUrl="http://localhost:7033/UserService/MetaData"/>
78         </behavior>
79         <behavior name="Service1Behavior" >
80           <serviceMetadata httpGetEnabled="true" httpGetUrl="http://localhost:6033/Service1/MetaData"/>
81         </behavior>
82       </serviceBehaviors>
83       <endpointBehaviors>
84         <behavior name="web">
85           <webHttp helpEnabled="true" />
86         </behavior>
87       </endpointBehaviors>
88     </behaviors>
89   </system.serviceModel>
90 
91   <system.web>
92     <globalization requestEncoding ="gb2312" responseEncoding ="gb2312"/>
93   </system.web>
94 </configuration>
app.config文件

WindowsServiceDemo1.cs代码:

wcf Rest 服务宿主在windows服务及客户端访问
  1 using System;
  2 using System.Collections.Generic;
  3 using System.Configuration;
  4 using System.Reflection;
  5 using System.ServiceModel;
  6 using System.ServiceModel.Configuration;
  7 using System.ServiceProcess;
  8 using log4net;
  9 
 10 [assembly: log4net.Config.DOMConfigurator(ConfigFile = "app.config", Watch = true)]
 11 namespace WindowsServiceDemo
 12 {
 13     public partial class WindowsServiceDemo1 : ServiceBase
 14     {
 15         /// <summary>
 16         /// 要启动的服务
 17         /// </summary>
 18         List<ServiceHost> listHost = null;
 19         ServiceHost host = null;
 20         private log4net.ILog logger = log4net.LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
 21 
 22         public WindowsServiceDemo1()
 23         {
 24             InitializeComponent();
 25         }
 26 
 27         protected override void OnStart(string[] args)
 28         {
 29             OpenServices();
 30         }
 31 
 32 
 33         public void OpenServices()
 34         {
 35             try
 36             {
 37                 listHost = new List<ServiceHost>();
 38                 Configuration conf = ConfigurationManager.OpenExeConfiguration(Assembly.GetEntryAssembly().Location);
 39                  
 40                 logger.Info("开始启动服务......");
 41                 if (conf != null)
 42                 {
 43                     ServiceModelSectionGroup svcmod = (ServiceModelSectionGroup)conf.GetSectionGroup("system.serviceModel");
 44                     foreach (ServiceElement el in svcmod.Services.Services)
 45                     {
 46                         logger.Debug("..."+el.Name );
 47                         string klassName = el.Name.Substring(el.Name.LastIndexOf(.) + 1);
 48                         logger.Debug("..1111." + conf.FilePath.Substring(0, conf.FilePath.LastIndexOf(\\)+1) +  klassName + ".dll");
 49                         Assembly asmb = Assembly.LoadFrom(conf.FilePath.Substring(0, conf.FilePath.LastIndexOf(\\)+1) + klassName + ".dll");
 50                         logger.Debug("..222..." );
 51                         Type svcType = asmb.GetType(el.Name);
 52                         logger.Debug("..333..." + svcType);
 53                         if (svcType == null)
 54                         {
 55                             continue;
 56                         }
 57                         host = new ServiceHost(svcType);
 58                         logger.Info(host.Description.Endpoints[0]);
 59 
 60                         logger.Info(el.Name + ":服务已经启动了");
 61                         host.Open();
 62                         logger.Debug("..444..." );
 63                         if (!listHost.Contains(host))
 64                         {
 65                             logger.Debug("..555...");
 66                             listHost.Add(host);
 67                             logger.Debug("..6666...");
 68                         }
 69                     }
 70                 }
 71                 else
 72                 {
 73                     logger.Warn("没有找到服务对应的配置信息");
 74                 }
 75             }
 76             catch (Exception ex)
 77             {
 78                 logger.Error(ex.Message);
 79             }
 80         }
 81         protected override void OnStop()
 82         {
 83             CloseServices();
 84         }
 85 
 86         void CloseServices()
 87         {
 88             try
 89             {
 90 
 91                 if (listHost != null && listHost.Count > 0)
 92                 {
 93 
 94                     foreach (ServiceHost host in listHost)
 95                     {
 96                         if (host != null)
 97                         {
 98                             host.Close();
 99                         }
100                     }
101 
102                 }
103             }
104             catch (Exception ex)
105             {
106 
107             }
108         }
109     }
110 }
View Code

Program.cs文件代码:

wcf Rest 服务宿主在windows服务及客户端访问
 1 using System.ServiceProcess;
 2 
 3 
 4 namespace WindowsServiceDemo
 5 {
 6     static class Program
 7     {
 8         /// <summary>
 9         /// 应用程序的主入口点。
10         /// </summary>
11         static void Main()
12         {
13             ServiceBase[] ServicesToRun;
14             ServicesToRun = new ServiceBase[] 
15             { 
16                 new WindowsServiceDemo1() 
17             };
18             ServiceBase.Run(ServicesToRun);
19         }
20     }
21 }
View Code

加入组件serviceInstaller1和serviceProcessInstaller1分别设置好服务名称、显示名称、及account等

使用命令安装服务:

installutil D:\WcfRestServiceDemo1\WcfRestServiceDemo1\WindowsServiceDemo\bin\Debug\WindowsServiceDemo1.exe

确保程序和服务都是管理员身份,启动服务。代码中已加入日志,在IE浏览器中输入“http://localhost:3723/EmployeesService”,若显示不出,则服务有问题,可查看日志文件找原因。

服务启动OK后,写控制台客户端代码:

在解决方案中新增一控制台项目为ClientConsoleDynamicProject,app.config文件不用配置,直接写program.cs文件,如下代码:

wcf Rest 服务宿主在windows服务及客户端访问
 1 using System;
 2 using System.Text;
 3 using Microsoft.Http;
 4 using Newtonsoft.Json.Linq;
 5 using System.Runtime.Serialization.Json;
 6 
 7 namespace ClientConsoleDynamicProject
 8 {
 9     class Program
10     {
11         static dynamic GetModel(string id,string name,string department,string grade,string isHire,string entryDate)
12         {
13             dynamic model=new JObject();
14             model.Id = id;
15             model.Name = name;
16             model.Department = department ;
17             model.Grade =grade ;
18             model.IsHire = isHire;
19             model.EntryDate = ConvertDateStringToJsonDate(entryDate);
20             return model;
21         }
22         private static string ConvertDateStringToJsonDate(string dateTime)
23         {
24             string result = string.Empty;
25             DateTime dt = DateTime.Parse(dateTime);
26             dt = dt.ToUniversalTime();
27             TimeSpan ts = dt - DateTime.Parse("1970-1-1");
28             result = string.Format("/Date({0}+0800)/", ts.TotalMilliseconds);
29             return result;
30         }
31 
32         static void Main(string[] args)
33         {
34             var client = new HttpClient();
35             var strUrl = "http://localhost:3723/EmployeesService/{0}";
36             strUrl = string.Format(strUrl, "2");
37             var response = client.Get(strUrl);
38             response.EnsureStatusIsSuccessful();
39             var json = response.Content.ReadAsString();
40             Console.WriteLine(json);
41 
42             //create
43             string jsonModel = GetModel("5","Jimmy as 张奇","文学部","G3","true","2012/09/05 12:23:08").ToString();
44             Console.WriteLine(jsonModel );
45             var data = Encoding.UTF8.GetBytes(jsonModel);
46             strUrl = "http://localhost:3723/EmployeesService/";
47             HttpContent content = HttpContent.Create( data,"application/json");
48             response = client.Post(strUrl, content);
49             response.EnsureStatusIsSuccessful();
50 
51             //get all
52             strUrl = "http://localhost:3723/EmployeesService/all";
53             response = client.Get(strUrl);
54             var xml = response.Content.ReadAsString();
55             Console.WriteLine("=============新增数据后,get all=============");
56             Console.WriteLine(xml);
57             #region update,delete
58             ////update
59             //strUrl = "http://localhost:3723/EmployeesService/";
60             //dynamic model = new JObject();
61             //model.Id = 2;
62             //model.Name = "牛牛";
63             //model.Department = "开发部";
64             //model.Grade = "G2";
65             //model.EntryDate = ConvertDateStringToJsonDate("2000/01/01");
66             //jsonModel = model.ToString();
67             //data = Encoding.UTF8.GetBytes(jsonModel);
68             //content = HttpContent.Create(data, "application/json");
69             //response = client.Put(strUrl, content);
70             //response.EnsureStatusIsSuccessful();
71 
72             ////delete
73             //strUrl = "http://localhost:3723/EmployeesService/{0}";
74             //strUrl = string.Format(strUrl, "7");
75             //response = client.Delete(strUrl);
76             //response.EnsureStatusIsSuccessful();
77             #endregion
78             //add
79             //jsonModel = GetModel("6", "小猫咪", "事业部", "G8", "true", "2013/07/02 22:08:52").ToString();
80             jsonModel = "\"{\\\"Department\\\":\\\"业务部\\\",\\\"EntryDate\\\":\\\"\\/Date(1372774132000+0800)\\/\\\",\\\"Grade\\\":\\\"G5\\\",\\\"Id\\\":10,\\\"IsHire\\\":true,\\\"Name\\\":\\\"张大伟\\\"}\"";
81             Console.WriteLine(jsonModel);
82             data = Encoding.UTF8.GetBytes(jsonModel);
83             strUrl = "http://localhost:3723/EmployeesService/Add";
84             content = HttpContent.Create(data, "application/json");
85             response = client.Post(strUrl, content);
86             //response = client.Delete(strUrl+jsonModel);
87             response.EnsureStatusIsSuccessful();
88 
89             //get all
90             strUrl = "http://localhost:3723/EmployeesService/all";
91             response = client.Get(strUrl);
92             json = response.Content.ReadAsString();
93             Console.WriteLine("=============get all=============");
94             Console.WriteLine(json);
95             Console.Read();
96         }
97     }
98 }
View Code

执行客户端程序,OK。

需要注意的:

1.json格式中日期转换的问题,代码中已处理。若不处理,默认时使用的ISO8601的日期格式,而它需要“\/Date(1234656000000)\/”形式的日期格式,否则总报“BadRequest (400)”错误。

2.客户端调用服务中Add方法时,参数是string,在post时字符串需作处理。比如:“ss”字符串,传入时需写成“\"ss\"”,也就是说引号必须传入才是它能接受的。否则也总报“BadRequest (400)”错误。

wcf Rest 服务宿主在windows服务及客户端访问,布布扣,bubuko.com

wcf Rest 服务宿主在windows服务及客户端访问

上一篇:AzurePack之SCVMM虚拟机WindowsServer2003模版


下一篇:Deskpool安装之:准备Windows 7虚拟机基础镜像