问题描述
我有一个 WCF 服务,其操作都需要 MyServiceRequest 参数(或派生类型)并返回 MyServiceResponse(或派生类型),即:
I have a WCF service with operations that all require MyServiceRequest parameter (or derived type)and returns MyServiceResponse (or dervived type), i.e.:
[OperationContract]
MySeviceResponse FindAppointments(FindAppointmentRequest request);
[OperationContract]
MyServiceResponse MakeAnAppointment(MakeAnAppointmentRequest request);
[OperationContract]
MyServiceResponse RegisterResource(RegisterResourceRequest request);
FindAppointmentRequest、MakeAnAppointmentRequest 和 RegisterResourceRequest 扩展了 MyServiceRequest,其中包含属性 UserName 和 UserPassword.
FindAppointmentRequest, MakeAnAppointmentRequest and RegisterResourceRequest extends MyServiceRequest which contains properties UserName and UserPassword.
如果请求中存在错误的用户名/用户密码对,则此方法均无法正确执行.
None of this method executes properly should there be wrong UserName/UserPassword pair in Request.
我想创建一个拦截器,它不仅检查给定的 UserName/UserPassword 对是否正确(使用 IParameterInspector 非常简单),而且还返回扩展 MyServiceResponse 的 ErrorRespone 类型的客户端对象.
I want to create an interceptor which not only checks if given UserName/UserPassword pair is correct (which is pretty simple with IParameterInspector) but also returns to the client object of type ErrorRespone that extends MyServiceResponse.
IParameterInspector 能否阻止服务执行请求的方法并立即返回 ErrorResponse?
推荐答案
IParameterInspector 可以通过抛出异常来阻止操作执行.这是一个例子.
IParameterInspector can prevent operation from executing by throwing an exception. Here's an example.
定义自定义故障合约:
public class DataAccessFaultContract
{
public string ErrorMessage { get; set; }
}
然后是检查员:
public class InspectorAttribute : Attribute, IParameterInspector, IOperationBehavior
{
public void AfterCall(string operationName, object[] outputs, object returnValue, object correlationState)
{
}
public object BeforeCall(string operationName, object[] inputs)
{
MyServiceRequest request = null;
if (inputs != null && inputs.Length > 0)
{
request = inputs[0] as MyServiceRequest;
}
if (request != null && request.Username != "user" && request.Password != "secret")
{
var fc = new DataAccessFaultContract{ ErrorMessage = "Invalid user" };
throw new FaultException<DataAccessFaultContract>(fc);
}
return null;
}
public void AddBindingParameters(OperationDescription operationDescription, BindingParameterCollection bindingParameters)
{
}
public void ApplyClientBehavior(OperationDescription operationDescription, ClientOperation clientOperation)
{
}
public void ApplyDispatchBehavior(OperationDescription operationDescription, DispatchOperation dispatchOperation)
{
dispatchOperation.ParameterInspectors.Add(this);
}
public void Validate(OperationDescription operationDescription)
{
}
}
最后用适当的属性装饰你的操作:
And finally decorate your operation with appropriate attributes:
[ServiceContract]
public interface IMyServiceContract
{
[Inspector]
[FaultContract(typeof(DataAccessFaultContract))]
[OperationContract]
MySeviceResponse FindAppointments(FindAppointmentRequest request);
...
}
在调用服务时,客户端可以检查FaultException:
When invoking the service, the client could check for FaultException:
try
{
var response = client.FindAppointments(request);
}
catch (FaultException<DataAccessFaultContract> ex)
{
string errorMessage = ex.Detail.ErrorMessage;
// ...
}
这篇关于使用拦截器验证 WCF 参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!