2013-04-24 2 views
1

Я хотел бы применить ограничения вызовов для своих методов обслуживания. Эти ограничения должны возвращать исключение Fault при достижении максимального количества вызовов на клиента.применить пользователя MaxAllowedCall по методу wcf

Первое решение, которое я нашел в том, чтобы кодировать логику в рамках услуги:

public class MyService: IService 
{ 

    public IList<Entity> FindAll() 
    { 
     if(VerifyQuota(Context, "FindAll", this.GetType().Name)) 
     { 
      //retrieves entities 
      return entities; 
     } 
     else 
     { 
      //throws a FaultException 
     } 
     return null; 
    } 

    private bool VerifyQuota(ContextEntity context,string Method,String Service) 
    { 
     // counts the occurences of calls made by the user 
     // returns true if user can access method , false otherwise 
    } 
} 

Он работает, но:

  • Это довольно некрасиво
  • Это загрязняет логику моего метода
  • код избыточность слишком высока, а ремонтопригодность - очень плохая.

Я ищу более элегантное решение и подумал об использовании IOperationBehavior, но не знаю, где я могу найти идентификатор пользователя.

OperationContext.Current не установлен и не является Thread.CurrentPrincipal.

Итак, вот мои вопросы: - это поведение, лучший способ реализовать такие функции? - Если да, то где я могу найти идентификатор пользователя (или вход в систему) - Если нет, где я могу поместить этот код, чтобы он вписывался в архитектуру WCF?

ответ

0

Я продолжал играть с Behaviors и узнал, что могу получить доступ к операционному контенту. Курант в IparameterInspector. Реализация

IparameterInspector: реализация

class QuotaInspector : IParameterInspector 
{ 
    #region IParameterInspector Members 

    public void AfterCall(string operationName, object[] outputs, object returnValue, object correlationState) 
    { 

    } 

    public object BeforeCall(string operationName, object[] inputs) 
    { 
     if(ServiceSecurityContext.Current != null) 
     { 
      if(ServiceSecurityContext.Current.PrimaryIdentity != null 
       && ServiceSecurityContext.Current.PrimaryIdentity.AuthenticationType == "MembershipProviderValidator") 
      { 
       String Account = String.Empty; 
       String serviceComponent = String.Empty; 
       if(!String.IsNullOrEmpty(ServiceSecurityContext.Current.PrimaryIdentity.Name)) 
        Account = ServiceSecurityContext.Current.PrimaryIdentity.Name; 
       if(OperationContext.Current != null && 
        OperationContext.Current.EndpointDispatcher != null 
        && OperationContext.Current.EndpointDispatcher.DispatchRuntime != null 
        && OperationContext.Current.EndpointDispatcher.DispatchRuntime.Type != null && 
        !String.IsNullOrEmpty(OperationContext.Current.EndpointDispatcher.DispatchRuntime.Type.Name)) 
        serviceComponent = ServiceSecurityContext.Current.PrimaryIdentity.Name; 
       if(!String.IsNullOrEmpty(Account) && !String.IsNullOrEmpty(serviceComponent) && !string.IsNullOrEmpty(operationName)) 
       { 
        //Apply Quota verification here 
              //throw FaultException if quota is reached 
       } 
      } 

     } 
     return null; 
    } 

    #endregion 
} 

IOperationBehavior:

class QuotaOperationBehavior : Attribute,IOperationBehavior 
{ 
    #region IOperationBehavior Members 

    public void AddBindingParameters(OperationDescription operationDescription, System.ServiceModel.Channels.BindingParameterCollection bindingParameters) 
    { 
    } 

    public void ApplyClientBehavior(OperationDescription operationDescription, System.ServiceModel.Dispatcher.ClientOperation clientOperation) 
    { 

    } 

    public void ApplyDispatchBehavior(OperationDescription operationDescription, System.ServiceModel.Dispatcher.DispatchOperation dispatchOperation) 
    { 
     dispatchOperation.ParameterInspectors.Add(new QuotaInspector()); 
    } 

    public void Validate(OperationDescription operationDescription) 
    { 
    } 

    #endregion 

} 

Чтобы применить квоту к способу вы просто должны объявить атрибут:

public class MyService: IService 
{ 

    [QuotaOperationBehavior] 
    public IList<Entity> FindAll() 
    { 
     //retrieves entities 
     return entities; 
    } 
} 
Смежные вопросы