WCF错误契约demo

作为一个小菜鸟,为了纪念wcf学习的过程,偶尔写写几篇博客,在前人的基础上简化下,这样学起来更轻松些。我感觉这个错误契约貌似是在封装服务端的异常。为了不直接暴露服务端的错误,经过自定义处理。项目结构简单明了:

自定义错误契约

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;

namespace Service
{
    /// <summary>
    /// 用于记录错误信息
    /// </summary>
     [DataContract]
    public class MathError
    {
        /// <summary>
        /// 出错的操作
        /// </summary>
        private string _operation;
        /// <summary>
        /// 出错的信息
        /// </summary>
        private string _errorMessage;

        public MathError(string operation, string errorMessage)
        {
            this._operation = operation;
            this._errorMessage = errorMessage;
        }

        [DataMember]
        public string Operation
        {
            get { return _operation; }
            set { _operation = value; }
        }

        [DataMember]
        public string ErrorMessage
        {
            get { return _errorMessage; }
            set { _errorMessage = value; }
        }
    }
}

服务契约

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;

namespace Service
{
    [ServiceContract]
    public interface ICalculator
    {

        /// <summary>
        /// 指定出现错误时返回的错误类型
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <returns></returns>
        [OperationContract]
        [FaultContract(typeof(MathError))]
        double Divide(double x, double y);
    }
}

实现:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;

namespace Service
{
    public class CalculatorService : ICalculator
    {
        #region ICalculator Members

        public double Divide(double x, double y)
        {
            if (y == 0)
            {
                //throw new DivideByZeroException("除数不能为0");
                MathError error = new MathError("Divide", "Divided by zero");
                throw new FaultException<MathError>(error, new FaultReason("Parameters passed are not valid"), new FaultCode("sender"));
            }
            return x / y;
        }

        #endregion
    }
}

服务寄宿:

using (ServiceHost calculatorHost = new ServiceHost(typeof(CalculatorService)))
            {
                calculatorHost.Opened += delegate
                {
                    Console.WriteLine("启动服务:{0}", calculatorHost.BaseAddresses[0]);
                };
                calculatorHost.Open();
                Console.Read();
            }

服务配置:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>

  <system.web>
    <compilation debug="true" />
  </system.web>
  <!-- 部署服务库项目时,必须将配置文件的内容添加到
 主机的 app.config 文件中。System.Configuration 不支持库的配置文件。 -->
  <system.serviceModel>
    <services>
      <service name="Service.CalculatorService" behaviorConfiguration="calculatorServiceBehavior">
        <host>
          <baseAddresses>
            <add baseAddress = "http://192.168.10.2:8733/Service/" />
          </baseAddresses>
        </host>
        <!-- Service Endpoints -->
        <!-- 除非完全限定,否则地址相对于上面提供的基址-->
        <endpoint
           address="http://192.168.10.2:8733/Service/" 
           binding="basicHttpBinding" 
           contract="Service.ICalculator">
          <!--
              部署时,应删除或替换以下标识元素,以反映
              在其下运行部署服务的标识。删除之后,WCF 将
              自动推导相应标识。
          -->
          <identity>
            <dns value="localhost"/>
          </identity>
        </endpoint>
        <!-- Metadata Endpoints -->
        <!-- 元数据交换终结点供相应的服务用于向客户端做自我介绍。 --> 
        <!-- 此终结点不使用安全绑定,应在部署前确保其安全或将其删除 -->
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="calculatorServiceBehavior">
          <!-- 为避免泄漏元数据信息,
          请在部署前将以下值设置为 false -->
          <serviceMetadata httpGetEnabled="True"/>
          <!-- 要接收故障异常详细信息以进行调试,
          请将以下值设置为 true。在部署前
            设置为 false 可避免泄漏异常信息 -->
          <serviceDebug includeExceptionDetailInFaults="true" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>
</configuration>

客户端引用:

using Service;
using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.Text;

namespace Client
{
    class Program
    {
        static void Main(string[] args)
        {
            ChannelFactory<ICalculator> calculatorFactory = new ChannelFactory<ICalculator>("defualtEndpoint");
            ICalculator calculator = calculatorFactory.CreateChannel();
            try
            {
                Console.WriteLine("准备执行除法");
                Console.WriteLine("x / y =  {2} when x = {0} and y = {1}", 2, 0, calculator.Divide(2,0));
            }
            catch (FaultException<MathError> ex)
            {
                MathError error = ex.Detail;
                Console.WriteLine("An Fault is thrown.\n\tFault code:{0}\n\tFault Reason:{1}\n\tOperation:{2}\n\tMessage:{3}", ex.Code, ex.Reason, error.Operation, error.ErrorMessage);
            }
            Console.Read();
        
        }
    }
}

客户端配置:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.serviceModel>
    <client>
     <endpoint address="http://192.168.10.2:8733/Service/"
     binding="basicHttpBinding"
     contract="Service.ICalculator"
     name="defualtEndpoint" />
    </client>
  </system.serviceModel>
</configuration>

也可以下载源码

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

90e家

有C币的小伙伴可以贡献一点,哈

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值