0

I'm using WCF custom Validator with HTTPS (.NET 4.5). Validate on success returns Customer object which I would like to use later. Currently I'm able to do it with Static variables which I like to avoid if possible. I tried to use HttpContext which becomes null in main thread. My understanding Validate runs under different thread. Is there any way I could share session info without involving DB or File share. See related threads here and here.

In Authentication.cs

public class CustomValidator : UserNamePasswordValidator
{ 
      public override void Validate(string userName, string password)
      {
       //If User Valid then set Customer object
      }
}

In Service.cs

  public class Service
  {
      public string SaveData(string XML)
      {
       //Need Customer object here. Without it cannot save XML. 
       //HttpContext null here.
      }
  }  
Community
  • 1
  • 1
Manish Jain
  • 9,569
  • 5
  • 39
  • 44

2 Answers2

1

I can suggest you an alternative approach. Assuming that the WCF service is running in ASP.Net compatibility mode and you are saving the customer object to session storage. Create a class such as AppContext

The code would look something like this

public class AppContext {
public Customer CurrentCustomer {
  get {
    Customer cachedCustomerDetails = HttpContext.Current.Session[CUSTOMERSESSIONKEY] as Customer;
        if (cachedCustomerDetails != null)
        {
            return cachedCustomerDetails;
        }
        else
        {
            lock (lockObject)
            {
                if (HttpContext.Current.Session[CUSTOMERSESSIONKEY] != null)        //Thread double entry safeguard
                {
                    return HttpContext.Current.Session[CUSTOMERSESSIONKEY] as Customer;
                }

                Customer CustomerDetails = ;//Load customer details based on Logged in user using HttpContext.Current.User.Identity.Name
                if (CustomerDetails != null)
                {
                    HttpContext.Current.Session[CUSTOMERSESSIONKEY] = CustomerDetails;
                }

                return CustomerDetails;
            }
        }
  }
}

The basic idea here is to do lazy loading of data, when both WCF and ASP.Net pipelines have executed and HTTPContext is available.

Hope it helps.

Chandermani
  • 42,589
  • 12
  • 85
  • 88
  • Thanks for response. I've already tried this solution. HttpContext goes out of scope when you go from Validate to SaveData method. FYI, also OperationContext null in Validate. – Manish Jain Feb 27 '13 at 17:42
  • Ok, Instead of HttpContext use OperationContext. You can get the username from OperationContext.Current.ServiceSecurityContext.PrimaryIdentity.Name. You dont add customer to session during Authenitcate. You add it to session when customer data is first requested. By this time the user is authenticated and Session is available to your service. – Chandermani Feb 28 '13 at 07:09
  • 1
    OperationContext is null in Validate. UserNamePasswordValidator runs in different context/thread. – Manish Jain Mar 05 '13 at 23:56
0

Alright this should have been easier. Since the way UserNamePasswordValidator works, I needed to use custom Authorization to pass UserName/Password to the main thread and get customer info again from the database. This is an additional DB call but acceptable workaround for now. Please download code from Rory Primrose's genius blog entry.

Manish Jain
  • 9,569
  • 5
  • 39
  • 44