我想处理我的服务客户端抛出的所有WebServiceException
。现在有一个很好的方法吗?
例如,我在Windows窗体应用程序周围传递一个ServiceClientBase。我在http标头中将api密钥传递给服务器。对于api密钥无效的任何请求,我想显示一个消息框,告诉用户该请求是未授权的,他们应该设置API密钥。但我不想在任何地方使用这个代码:
try
{
_client.Get(new ReqDto());
}
catch (WebServiceException ex)
{
if(ex.StatusCode == 401)
Util.ShowUnauthorizedMessageBox();
}
这样的事情会很好:
_client.WebServiceExceptionHandler += TheHandler;
我知道有可以挂钩的本地响应过滤器,但我需要物化的WebServiceException。
我正在查看ServiceClientBase.cs以了解我能做些什么,但我会感激任何帮助。感谢。
答案 0 :(得分:2)
如果我可以将其视为设计问题,而不是API问题,那么答案就是包装您的服务客户端。就个人而言,我做了类似的事情,所以我可以在客户端上记录服务异常。
这可能是一个起点:
public class MyServiceClient : IDisposable
{
public ServiceClientBase ServiceClient { get; set; }
string _serviceUri;
public string ServiceUri
{
get { return _serviceUri; }
set { _serviceUri = value; ServiceUriChanged(); }
}
public MyServiceClient()
{
ServiceUri = "http://127.0.0.1:8080";
}
public void Dispose()
{
ServiceClient.Dispose();
}
public TResponse Get<TResponse>(IReturn<TResponse> request)
{
try
{
return ServiceClient.Get(request);
}
catch (WebServiceException ex)
{
if(ex.StatusCode == 401)
Util.ShowUnauthorizedMessageBox();
}
}
void ServiceUriChanged()
{
if (ServiceClient != null)
ServiceClient.Dispose();
ServiceClient = new JsonServiceClient(ServiceUri);
}
}
随着时间的推移,您可能会发现这种额外的间接级别的其他好处,例如添加本地缓存,记录所有请求和&amp;响应[到调试控制台]。而且,一旦它在您的所有客户端代码中使用,维护起来相当便宜。
就API而言,我不认为它提供了你想要的东西。就个人而言,我一直很满意(特别是IReturn<T>
界面在整合你想要的功能时有帮助)。但是,如果你对它不满意,那么你就可以通过Demis与{{3}}对话提出改进请求。 ( - =
答案 1 :(得分:1)
游戏有点晚了,但是我遇到了同样的事情,所以开始深入挖掘源头。实际上有一个简单的解决方法,在您使用的任何ServiceClient中覆盖HandleResponseException
方法。直接来自评论:
/// <summary>
/// Called by Send method if an exception occurs, for instance a System.Net.WebException because the server
/// returned an HTTP error code. Override if you want to handle specific exceptions or always want to parse the
/// response to a custom ErrorResponse DTO type instead of ServiceStack's ErrorResponse class. In case ex is a
/// <c>System.Net.WebException</c>, do not use
/// <c>createWebRequest</c>/<c>getResponse</c>/<c>HandleResponse<TResponse></c> to parse the response
/// because that will result in the same exception again. Use
/// <c>ThrowWebServiceException<YourErrorResponseType></c> to parse the response and to throw a
/// <c>WebServiceException</c> containing the parsed DTO. Then override Send to handle that exception.
/// </summary>
我个人在覆盖JsonServiceClient
protected override bool HandleResponseException<TResponse>(Exception ex, object request, string requestUri, Func<System.Net.WebRequest> createWebRequest, Func<System.Net.WebRequest, System.Net.WebResponse> getResponse, out TResponse response)
{
Boolean handled;
response = default(TResponse);
try
{
handled = base.HandleResponseException(ex, request, requestUri, createWebRequest, getResponse, out response);
}
catch (WebServiceException webServiceException)
{
if(webServiceException.StatusCode > 0)
throw new HttpException(webServiceException.StatusCode, webServiceException.ErrorMessage);
throw;
}
return handled;
}