使用Interceptor进行WCF参数验证

时间:2009-11-28 10:24:52

标签: wcf validation service parameters

我有一个WCF服务,其操作都需要MyServiceRequest参数(或派生类型) 并返回MyServiceResponse(或衍生类型),即:

    [OperationContract]
    MySeviceResponse FindAppointments(FindAppointmentRequest request);

    [OperationContract]
    MyServiceResponse MakeAnAppointment(MakeAnAppointmentRequest request);

    [OperationContract]
    MyServiceResponse RegisterResource(RegisterResourceRequest request);

FindAppointmentRequest,MakeAnAppointmentRequest和RegisterResourceRequest扩展MyServiceRequest,其中包含UserName和UserPassword属性。

如果Request中有错误的UserName / UserPassword对,则此方法都不会正确执行。

我想创建一个拦截器,它不仅会检查给定的UserName / UserPassword对是否正确(使用IParameterInspector非常简单),还会返回扩展MyServiceResponse的ErrorRespone类型的客户端对象。

IParameterInspector可以阻止服务执行请求的方法并返回ErrorResponse strightaway吗?

2 个答案:

答案 0 :(得分:22)

IParameterInspector可以通过抛出异常来阻止执行操作。这是一个例子。

定义自定义故障合同:

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)
    {
    }
}

最后用适当的属性装饰你的操作:

[ServiceContract]
public interface IMyServiceContract
{
    [Inspector]
    [FaultContract(typeof(DataAccessFaultContract))]
    [OperationContract]
    MySeviceResponse FindAppointments(FindAppointmentRequest request);

    ...
}

调用服务时,客户端可以检查FaultException:

try
{
    var response = client.FindAppointments(request);
}
catch (FaultException<DataAccessFaultContract> ex)
{
    string errorMessage = ex.Detail.ErrorMessage;
    // ...
}

答案 1 :(得分:0)

你可以有一个方法返回一个bool(True / False)来检查你在上述每个方法的条目中的参数,然后你可以检查这是否返回true或false并返回或执行相应的方法

所以

bool paramtest = CheckParams(string username, string passw);

if ( paramtest )
{
// Continue method here
}
else
{ 
return false; // or return some string with error 
}

将其放在上述所有方法中......其中CheckParams是您从IParameterInspector验证参数的方法。