Проверка параметров WCF с помощью перехватчика - PullRequest
9 голосов
/ 28 ноября 2009

У меня есть служба WCF с операциями, для которых всем требуется параметр MyServiceRequest (или производный тип) и возвращает MyServiceResponse (или производный тип), то есть ::1001*

    [OperationContract]
    MySeviceResponse FindAppointments(FindAppointmentRequest request);

    [OperationContract]
    MyServiceResponse MakeAnAppointment(MakeAnAppointmentRequest request);

    [OperationContract]
    MyServiceResponse RegisterResource(RegisterResourceRequest request);

FindAppointmentRequest, MakeAnAppointmentRequest и RegisterResourceRequest расширяет MyServiceRequest, который содержит свойства UserName и UserPassword.

Ни один из этих методов не выполняется должным образом, если в запросе указана неправильная пара UserName / UserPassword.

Я хочу создать перехватчик, который не только проверяет правильность заданной пары UserName / UserPassword (что довольно просто с IParameterInspector), но также возвращает клиентскому объекту типа ErrorRespone, который расширяет MyServiceResponse.

Может ли IParameterInspector помешать службе выполнить запрошенный метод и вернуть ответ ErrorResponse?

Ответы [ 2 ]

22 голосов
/ 28 ноября 2009

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;
    // ...
}
0 голосов
/ 28 ноября 2009

У вас может быть метод, который возвращает 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 для проверки ваших параметров.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...