公司項目需要做一個Android和服務器交互的應用,並且服務端越簡單越好,最好不要用IIS。
WCF正符合這個需要,他的Host既可以寄宿在IIS中,也可以寄宿在普通的應用程序中。
下面介紹我的工作吧
創建項目
創建如下的三個項目:
Service:一個類庫項目,我把WCF中的Services和Contracts(契約)都放在其中了,注意添加System.ServiceModel和System.ServiceModel.Web兩個引用。
Host:一個命令行應用程序,用來承載Service;自然,得添加Service的引用。
Client:一個Winform應用程序,用於和Host交互,測試服務的可用性。
編寫Service
Service有兩部分構成,服務和契約:

[ServiceContract] public interface IService { [OperationContract] ImageInfo GetImageInfo(string id); [OperationContract] Stream GetImageContent(string id); }

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特性:

[DataContract] public class ImageInfo { [DataMember] public string Id { get; set; } [DataMember] public string Name { get; set; } }
編寫Host
Host的代碼很簡單,只需要把WCF服務啟動即可:

static void Main() { using (var host = new ServiceHost(typeof(ImageService.Service.Service))) { host.Open(); Console.WriteLine("服務已經啟動!"); Console.Read(); } }
之后添加配置文件App.config:

<?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進行通信,直接貼代碼就是:

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();
}
}
最后上個效果圖,