0

I've implemented a WCF service which is using WebServiceHost and WebHttpBinding. I'm manually performing Basic Authentication via a call like this at the beginning of each method call:

User u = GetAuthenticatedUser();

Where GetAuthenticatedUser is using WebOperationContext.Current.IncomingRequest.Headers["Authorization"] header to authenticate user against entries in a database.

The problem that I'm having is that I'm making a call to GetAuthenticatedUser multiple times within a single service call because my methods don't pass around the User object.

Is there anything for WCF which represents a per service call "state" where information can be saved?

Mitch
  • 21,223
  • 6
  • 63
  • 86
bpeikes
  • 3,495
  • 9
  • 42
  • 80
  • 1
    Look at Per session instances http://www.codeproject.com/Articles/188749/WCF-Sessions-Brief-Introduction. – Mitch Feb 24 '14 at 18:56
  • I read the whole thing, but it doesn't appear to talk about anything in WCF which contains call state. Only sessions and instance contexts. I'm not looking to keep state through multiple calls. I want to associate some data with a particular call which would get cleared when the call was complete. The alternative, is to pass information about the user making the call into every function. I can do that, but I was hoping that there was something like a CallState object. – bpeikes Feb 25 '14 at 08:39
  • Also, @Mitch, simply posting a link to an article is not the best way to respond to a StackOverflow question. Links can get moved, and/or the content can change. It also doesn't answer the question. – bpeikes Feb 25 '14 at 08:41
  • re: link to article, I was short on time. That is why it is a comment, not an answer – Mitch Feb 25 '14 at 15:12
  • should have been clearer in your post – Brian Feb 26 '14 at 07:55

2 Answers2

1

Use an extension of OperationContext:

public class UserContext : IExtension<OperationContext>
{
    public User User { get; set; }

    public static User CurrentUser
    {
        set
        {
            UserContext context = OperationContext.Current.Extensions.Find<UserContext>();
            if (context == null)
            {
                context = new UserContext();
                OperationContext.Current.Extensions.Add(context);
            }
            context.User = value;
        }
        get
        {
            UserContext context = OperationContext.Current.Extensions.Find<UserContext>();
            if (context == null)
            {
                return null;
            }
            return context.User;
        }
    }

    public void Attach(OperationContext owner) { }
    public void Detach(OperationContext owner) { }
}

Example use:

UserContext.CurrentUser = new User("foo");
var user = UserContext.CurrentUser;

Related: Where to store data for current WCF call? Is ThreadStatic safe?

Community
  • 1
  • 1
Mitch
  • 21,223
  • 6
  • 63
  • 86
  • Thanks. I'll take a look at this and see if it works. I'll have to read a bit more about 'OperationContext.Current' – bpeikes Feb 25 '14 at 21:39
0

The short answer is No, there's no way to save sessions state with BasicHTTPBinding or webHTTPBinding (short of writing state values to a database for subsequent retrieval); both work like web servers, not saving anything from request to request.

But I think you can with wsHttpBinding, which isn't too different from webHttpBinding. Take a look at this link and see if it will work for you.

Community
  • 1
  • 1
Brian
  • 3,653
  • 1
  • 22
  • 33
  • I didn't say that I want to save anything from request to request. I want to save state during a single operation. – bpeikes Feb 25 '14 at 21:37