当前位置:坤哥网-kungge-WCF使用介绍(二):手动创建WCF服务

WCF使用介绍(二):手动创建WCF服务

2017/7/30 19:04:06 kungge阅读(54) 评论(0)


上一篇文章介绍了WCF的程序使用,代理类和配置文件都是自动生成的,这篇文章介绍手动创建一个WCF服务程序并调用它。


本次以一个例子进行演示,WCF服务提供CRUD基本操作。


项目结构介绍


新建一个解决方案,项目结构如下:

3c38be39-55c1-4a98-9b21-b3bc6ea2394b.png

Business项目文件夹:由实现业务方面类库组成。

WCF.Common:一些帮助类。

WCF.DAL:数据访问层,实现数据库CRUD操作。

WCF.Model:实体对象,定义数据契约。

WCF.Service:服务契约的接口和服务契约的具体实现类。


Client项目文件夹:包含的是客户端,可以是控制台应用程序、Winform、Web等。

WCF.Hosting:控制台应用程序,用来寄宿服务,即将WCF.Service寄宿在此。

WCF.Web:Web应用程序,调用WCF服务。


创建数据库表


本次数据库表采用的是商品表,之前制作爬虫用来存储爬取国美商城的商品,建表语句:

CREATE TABLE [dbo].[GM_Commodity_001](
    [Id] [int] IDENTITY(1,1) NOT NULL,
    [ProductId] [bigint] NULL,
    [CategoryId] [int] NULL,
    [Title] [nvarchar](500) NULL,
    [Price] [decimal](18, 2) NULL,
    [Url] [varchar](1000) NULL,
    [ImageUrl] [varchar](1000) NULL,
CONSTRAINT [PK_GM_Commodity_001] PRIMARY KEY CLUSTERED 
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY];


创建业务类库


将类库Common、DAL、Model、Service创建好,Common、DAL没什么特别之处。

下面特别说明Model和Service。

Model层要给类添加特性DataContract,给类成员添加特性DataMember,这两个特性需要添加引用System.Runtime.Serialization,代码如下:

[DataContract]
public class Commodity
{
    [DataMember]
    public int Id { get; set; }
    [DataMember]
    public long ProductId { get; set; }
    [DataMember]
    public int CategoryId { get; set; }
    [DataMember]
    public string Title { get; set; }
    [DataMember]
    public decimal Price { get; set; }
    [DataMember]
    public string Url { get; set; }
    [DataMember]
    public string ImageUrl { get; set; }

}

Service中包含接口IProcCommodity和类ProcCommodity,ProcCommodity实现IProcCommodity,没什么特别之处。IProcCommodity类则需要添加特性ServiceContract,方法添加特性OperationContract,这两个类要引用System.ServiceModel.dll,两个类如下:

    [ServiceContract]
    public interface IProcCommodity
    {
        /// <summary>
        /// 根据Id获取一个商品
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [OperationContract]
         Commodity GetCommodityById(int id);
        /// <summary>
        /// 根据类别获取商品
        /// </summary>
        /// <param name="categoryId"></param>
        /// <returns></returns>
        [OperationContract]
        List<Commodity> GetCommodityListByCategoryId(int categoryId);

        /// <summary>
        /// 插入一条商品记录
        /// </summary>
        /// <param name="commodity"></param>
        /// <returns></returns>
        [OperationContract]
        bool Insert(Commodity commodity);

        /// <summary>
        /// 删除一个商品
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [OperationContract]
        bool Delete(int id);
    }
    public class ProcCommodity:IProcCommodity
    {
        private static IDBHelper iDbHelper = new SqlHelper();
        
        /// <summary>
        /// 根据Id获取一个商品
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public Commodity GetCommodityById(int id)
        {
            return iDbHelper.QueryById<Commodity>(id);
        }
        /// <summary>
        /// 根据类别获取商品
        /// </summary>
        /// <param name="categoryId"></param>
        /// <returns></returns>
        public List<Commodity> GetCommodityListByCategoryId(int categoryId)
        {
            //5
            string sql = string.Format($"select * from [GM_Commodity_001] where CategoryId={categoryId}");
            return iDbHelper.QueryList<Commodity>(sql);
        }

        /// <summary>
        /// 插入一条商品记录
        /// </summary>
        /// <param name="commodity"></param>
        /// <returns></returns>
        public bool Insert(Commodity commodity)
        {
            var result=iDbHelper.Insert<Commodity>(commodity, "GM_Commodity_001");
            return result.Success;
        }

        /// <summary>
        /// 删除一个商品
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public bool Delete(int id)
        {
            return iDbHelper.DeleteById<Commodity>(id, "GM_Commodity_001")>0;
        }
    }


创建Hosting


控制台应用程序用来寄宿WCF服务,

在App.Config中添加相关节点用来寄宿服务,配置文件如下:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  
  <system.serviceModel>
    <services>
      <service name="WCF.Service.ProcCommodity" behaviorConfiguration="ProcCommodityBehavior">
        <host>
          <baseAddresses>
            <add baseAddress="http://127.0.0.1:52016/ProcCommodity/"/>
          </baseAddresses>
        </host>
        <endpoint address="" binding="wsHttpBinding" contract="WCF.Service.IProcCommodity"/>
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
      </service>
    </services>
 
    <behaviors>
      <serviceBehaviors>
        <behavior name="ProcCommodityBehavior">
          <serviceMetadata httpGetEnabled="True"/>
          <serviceDebug includeExceptionDetailInFaults="True"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>
 
    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
    </startup>
</configuration>

数据库链接字符串配置可以放在这个文件中。

在程序入口需要启动相关的服务:

static void Main(string[] args)
{
    try
    {
        List<ServiceHost> hostList = new List<ServiceHost>()
        {
            new ServiceHost(typeof(ProcCommodity)),
        };
        foreach (ServiceHost host in hostList)
        {
            host.Open();
            Console.WriteLine("{0}已经启动!", host.Description);
        }
        Console.WriteLine("按任意键停止服务");
        Console.ReadKey();

        foreach (ServiceHost host in hostList)
        {
            host.Abort();
        }
        Console.WriteLine("服务已关闭...");

        Console.ReadKey();
    }
    catch (Exception ex)
    {
        Console.WriteLine($"服务异常:{ex.Message}");
    }
}

ServiceHost需要引用System.ServiceModel。



调用WCF服务


Web应用程序用来调用WCF服务(也叫消费服务)。

要调用WCF服务,则需先通过寄宿的控制台应用程序来启动服务,先编译WCF.Hosting,然后在生成的bin中找到exe程序:

dc477aca-bcec-404e-b06f-962c397d3a90.png


运行这个exe程序,启动服务:

611abe9f-da74-4d65-aaa6-cef47f4469c3.png

在浏览器中打开http://127.0.0.1:52016/ProcCommodity/,如下表示服务创建成功:9d097f75-1817-4d07-8d50-ed959266c7f2.png

后面的使用同第一篇文章在.NET中使用WCF介绍(一)介绍一样。

在WCF.Web中添加服务引用:

b8fed5ab-cad3-4318-bddb-8bc8e6befa9a.png

确定之后双击刚才添加的引用,可以看到可调用的方法:

e47e5b2b-7015-47ca-a0b4-d28942853e46.png

新建一个控制器WCFShowController,在控制器新增一个视图用来显示调用结果,为了演示方便本次调用一次完成,数据用代码生成:

public class WCFShowController : Controller
{
    // GET: WCFShow
    public ActionResult Index()
    {
        try
        {
            StringBuilder sb = new StringBuilder();
            ProcCommodityClient client = new ProcCommodityClient();

            //新增
            sb.Append("**********开始调用新增数据接口******<br/>");
            Commodity commodity = new Commodity();
            commodity.ProductId = Convert.ToInt64(DateTime.Now.ToString("yyyyMMddHHmmss"));
            commodity.CategoryId = DateTime.Now.Day;
            commodity.Title = "建军90周年纪念册" + DateTime.Now.ToString("yyyyMMddHHmm");
            commodity.Price = DateTime.Now.Millisecond;
            commodity.Url = "http://www.kungge.com/" + DateTime.Now.ToString("yyyyMMddHHmmss");
            commodity.ImageUrl = "http://img.kungge.com/" + DateTime.Now.ToString("yyyyMMddHHmmss") + ".jpg";
            bool insertResult = client.Insert(commodity);
            sb.AppendFormat($"**********调用新增数据接口完成 新增结果:{insertResult}******<br/><br/>");

            //查询一个商品
            sb.Append("**********开始调用查询一个商品接口******<br/>");
            var queryResult=client.GetCommodityById(30);
            sb.AppendFormat($"**********调用查询一个商品接口完成 查询结果:{queryResult.Title}******<br/><br/>");

            //查询商品列表
            sb.Append("**********开始调用根据商品类别查询商品列表接口******<br/>");
            var commodityList = client.GetCommodityListByCategoryId(53);
            sb.AppendFormat($"**********调用完成 查询结果:{string.Join(",", commodityList.Select(x=>x.Title))}******<br/><br/>");

            //删除一个商品
            sb.Append("**********开始调用删除一个商品接口******<br/>");
            var delResult = client.Delete(30);
            sb.AppendFormat($"**********调用完成 删除结果:{delResult}******<br/><br/>");

            ViewBag.ShowMsg = sb.ToString();
        }
        catch(Exception ex)
        {
            ViewBag.ShowMsg = string.Format($"出错了:{ex.Message}");
        }

        //查询
        return View();
    }
}

在视图中直接显示调用结果:

@{
    ViewBag.Title = "Index";
}

@Html.Raw(ViewBag.ShowMsg)

调用结果:

6da6d56b-5c38-411c-a311-cb978c1a3037.png


自此手动创建WCF服务就介绍到这,CRUD没有实现U的操作,都一样,这里就不作介绍了,在看这篇文章的你自己去实现吧。



WCF

发表评论 没有账号,注册评论

博主

  • 用户名:kungge
  • 昵称:kungge

文章标签