Access current InstanceContext instance in WCF UsernamePasswordValidator

I have a WCF service that uses a custom UserPasswordValidator. The validator must access the context of the environment of my object.

I would like to create one ObjectContext for the whole service call, and then destroy it at the end of the call. So I created a static singleton class that provided this functionality, however, what is happening now is that if two calls to the service happen simultaneously, one of the calls provides a singleton.

I either keep a local reference to the ObjectContext, and in this case the second service that uses it sees it as deleted, throws it wrong, or I put the wrapper property around the Singleton class where necessary, and then all my changes are discarded because I get a new instance of the object if another call placed it.

So basically, my question is how to instantiate an ObjectContext for a single service call?

NOTE. The instance must be available both in the service code and in the user code UserPasswordValidator.

I cannot just do this in the constructor or use the using statement, because the custom UsernamePasswordValidator does not have access to it . Is there a way to have a static class for every call? It sounds impossible, but how does it happen? Should I cache an object in a session?

My service is hosted on IIS.

UPDATE:
Thus, I nailed this to state persistence in a Context instance using an IExtension object. But how do I access the current InstanceContext instance in UserPasswordValidator?

+3
source share
6 answers

Ok, so in the end I solved this using the following static class and relying on ASP.NET to cache the context for me.

, -, ObjectContext , , , , , .

public static class MyContextProvider
    {
        public static MyModel Context
        {
            get
            {
                if (HttpContext.Current.Items["context"].IsNull())
                {
                    HttpContext.Current.Items["context"] = new MyModel();
                }

                return HttpContext.Current.Items["context"] as MyModel;
            }
        }    
    }

, ObjectContext ,

var context = MyContextProvider.Context;
+2

, 1 .

, , using () { } OperationContract.

+1

, , ObjectContext WCF :

public static class EntityModelProvider
{
    private static readonly Dictionary<OperationContext, MyEntityModel> _entityModels = new Dictionary<OperationContext, MyEntityModel>();

    public static MyEntityModel GetEntityModel()
    {
        if (OperationContext.Current == null)
            throw new Exception("OperationContext is missing");

        lock (_entityModels)
        {
            if (!_entityModels.ContainsKey(OperationContext.Current))
            {
                _entityModels[OperationContext.Current] = new MyEntityModel();
                OperationContext.Current.OperationCompleted += delegate
                {
                    lock (_entityModels)
                    {
                        _entityModels[OperationContext.Current].Dispose();
                        _entityModels.Remove(OperationContext.Current);
                    }
                };
            }

            return _entityModels[OperationContext.Current];
        }
    }
+1

, :

[ServiceBehaviour(InstanceContextMode = InstanceContextMode.PerCall)]
public class MyService : IMyService {
    ObjectContext context;
}
0

CustomValidator, - , . Service CutomUserNameValidator..

, : ObjectContext - CustomValidator. , , . , , , - . - - , , .

public DynamicObjectContextObjectClass
{
  ObjectContext internalObjectContext;

}
public class ServiceUserNamePasswordValidator : UserNamePasswordValidator
{

    public DynamicObjectContextObjectClass dynamiccontext;


    public override void Validate(string userName, string password)
    {
        if(dynamiccontext.internalObjectContext.isdisposed)
        {

        dynamiccontext.internalObjectContext = new Context;

            }
            try
            {
                if (string.IsNullOrEmpty(userName) || password == null)
                {
                    //throw new ArgumentNullException();
                    throw new FaultException("Username cannot be null or empty; Password cannot be null and should not be empty");
                }
       }
   }
} 
0
source

Source: https://habr.com/ru/post/1756152/


All Articles