其他分享
首页 > 其他分享> > 给WCF服务添加全局错误捕获

给WCF服务添加全局错误捕获

作者:互联网

1,实现IErrorHandler类如下

// 自定义错误处理: 屏蔽发送给客户端错误信息,自己处理错误信息
public class ErrorHandler : IErrorHandler
{
	private string _time = ""; //记录错误发生的时间,以便到日志文件中查询错误信息

	//由于调用 ProvideFault 时,客户端处于阻塞状态,不要在这里进行长时间的操作
	public void ProvideFault(Exception error, MessageVersion version, ref Message msg)
	{
		//避免敏感信息泄漏,例如:数据库配置, error包含的错误信息应该记录到服务器的日志中,不能显示给客户端
		// FaultException<int> e = new FaultException<int>(123, error.Message);
		DateTime now = DateTime.Now;
		_time = now.ToString("yyyyMMddHHmmssfff", DateTimeFormatInfo.InvariantInfo);// "" + now.Year.ToString() + now.Month.ToString() + now.Day.ToString() + now.Hour.ToString() + now.Minute.ToString() + now.Second.ToString() + now.Millisecond.ToString();
		string errorMsg = "服务端错误:" + _time;
		// FaultException fe = new FaultException(errorMsg);
		// MessageFault mf = fe.CreateMessageFault();
		// msg = Message.CreateMessage(version, mf, fe.Action);//返回的将是一个xml

		//The fault to be returned
		msg = Message.CreateMessage(version, "", errorMsg, new DataContractJsonSerializer(typeof(string)));

		// tell WCF to use JSON encoding rather than default XML
		WebBodyFormatMessageProperty wbf = new WebBodyFormatMessageProperty(WebContentFormat.Json);

		// Add the formatter to the fault
		msg.Properties.Add(WebBodyFormatMessageProperty.Name, wbf);

		//Modify response
		HttpResponseMessageProperty rmp = new HttpResponseMessageProperty();

		// return custom error code, 500.
		rmp.StatusCode = System.Net.HttpStatusCode.InternalServerError;
		rmp.StatusDescription = "InternalServerError";

		//Mark the jsonerror and json content
		rmp.Headers[HttpResponseHeader.ContentType] = "application/json";
		rmp.Headers[HttpResponseHeader.ContentEncoding] = "utf-8";
		rmp.Headers["jsonerror"] = "true";

		//Add to msg
		msg.Properties.Add(HttpResponseMessageProperty.Name, rmp);
	}

	//HandleError 在异常返回给客户端之后被触发
	//自定义错误信息,例如在数据库中添加一个记录
	public bool HandleError(Exception error)
	{
		string errorMsg = error.Message + " ===== " + error.StackTrace;
		AppLog.Error("", error);  //在这里记录日志
		return false;
	}
}

2,写一个API的基类继承IServiceBehavior如下

[AspNetCompatibilityRequirements(RequirementsM
ode = AspNetCompatibilityRequirementsMode.Allowed)]
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)]
public class BasApi : IServiceBehavior
{
	protected BasApi()
	{
	}

	public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
	{
	}

	public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints,
		BindingParameterCollection bindingParameters)
	{
	}

	//调用服务第三步:异常抛转设定
	public void ApplyDispatchBehavior(ServiceDescription serviceDescription, System.ServiceModel.ServiceHostBase serviceHostBase)
	{
		IErrorHandler handler = new ErrorHandler();
		foreach (ChannelDispatcher dispatcher in serviceHostBase.ChannelDispatchers)
		{
			dispatcher.ErrorHandlers.Add(handler);
		}
	}
}

3,测试一下

[ServiceContract]
public class TestApi : BasApi
{
   [OperationContract]
	public void DoWork()
	{
		string a = null;
		int b = a.Length;
	}
}

标签:rmp,捕获,error,ToString,WCF,new,全局,now,public
来源: https://blog.csdn.net/zheyiw/article/details/100779665