代码改变世界

使用WCF创建Restful服务

2012-04-27 18:51 by 贼寇在何方, ... 阅读, ... 评论, 收藏, 编辑

公司项目需要做一个Android和服务器交互的应用,并且服务端越简单越好,最好不要用IIS。

WCF正符合这个需要,他的Host既可以寄宿在IIS中,也可以寄宿在普通的应用程序中。

下面介绍我的工作吧

 

创建项目

创建如下的三个项目:

Service:一个类库项目,我把WCF中的ServicesContracts(契约)都放在其中了,注意添加System.ServiceModelSystem.ServiceModel.Web两个引用。

Host:一个命令行应用程序,用来承载Service;自然,得添加Service的引用。

Client:一个Winform应用程序,用于和Host交互,测试服务的可用性。

 

编写Service

Service有两部分构成,服务和契约:

View Code
[ServiceContract]
public interface IService
{
    [OperationContract]
    ImageInfo GetImageInfo(string id);

    [OperationContract]
    Stream GetImageContent(string id);
}
View Code
public class Service : IService
{
    [WebGet(UriTemplate = "/ImageInfo/{id}/", ResponseFormat = WebMessageFormat.Json)]
    public ImageInfo GetImageInfo(string id)
    {
        return new ImageInfo
        {
            Id = id,
            Name = "NoName",
        };
    }

    [WebGet(UriTemplate = "/ImageContent/{id}/")]
    public Stream GetImageContent(string id)
    {
        WebOperationContext.Current.OutgoingResponse.ContentType = "image/png";

        string file = Path.Combine(Environment.CurrentDirectory, "picture.png");
        return File.OpenRead(file);
    }
}

 复杂类型的定义也是要的,注意给类加上DataContract特性,给需要序列化的属性加上DataMember特性:

View Code
[DataContract]
public class ImageInfo
{
    [DataMember]
    public string Id { get; set; }

    [DataMember]
    public string Name { get; set; }
}

 

编写Host

Host的代码很简单,只需要把WCF服务启动即可:

View Code
static void Main()
{
    using (var host = new ServiceHost(typeof(ImageService.Service.Service)))
    {
        host.Open();
        Console.WriteLine("服务已经启动!");
        Console.Read();
    }
}

之后添加配置文件App.config:

View Code
<?xml version="1.0"?>
<configuration>
  <system.serviceModel>
    <services>
      <service name="ImageService.Service.Service">
        <host>
          <baseAddresses>
            <add baseAddress="http://127.0.0.1:8888/"/>
          </baseAddresses>
        </host>
        <endpoint address="" binding="webHttpBinding" contract="ImageService.Service.IService" 
                  behaviorConfiguration="behavior">
        </endpoint>
      </service>
    </services>
    <behaviors>
      <endpointBehaviors>
        <behavior name="behavior">
          <webHttp/>
        </behavior>
      </endpointBehaviors>
    </behaviors>
  </system.serviceModel>
<startup>
  <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
</startup>
</configuration>

注意填写服务的完整类名称、契约的接口名称:

 

编写Client

客户端没什么难度,就是和Host进行通信,直接贴代码就是:

View Code
void btnGetImageInfo_Click(object sender, EventArgs e)
{
    var data = GetData("/ImageInfo/1/");
    var s = Encoding.Default.GetString(data);
    imageInfo.Text = s;
}

void btnGetImageContent_Click(object sender, EventArgs e)
{
    var data = GetData("/ImageContent/1/");
    using (var ms = new MemoryStream(data))
    {
        var image = new Bitmap(ms);
        imageContent.Image = image;
    }
}

byte[] GetData(string uri)
{
    var request = (HttpWebRequest)WebRequest.Create(
        "http://127.0.0.1:8888" + uri);

    var response = request.GetResponse();
    using (var ms = new MemoryStream())
    {
        var buffer = new byte[10240];
        using (var ns = response.GetResponseStream())
        {
            int i = ns.Read(buffer, 0, buffer.Length);
            while (i > 0)
            {
                ms.Write(buffer, 0, i);
                i = ns.Read(buffer, 0, buffer.Length);
            }
        }

        return ms.ToArray();
    }
}

 

最后上个效果图,

 

参考链接

我的WCF之旅(1):创建一个简单的WCF程序

异步调用Restful的WCF服务

用Restful方式调用WCF进行上传下载

WCF 部署问题小总结(HTTP 不能注册的解决方法和部署Bat脚本)