1

Possible Duplicate:
How to add custom soap headers in wcf?

Here's the scenario:

I have a WCF service which we'll call "BusinessService."

I also have a web app which has a client of this service to send requests.

I want to be able to log who is sending an update to my service; because of this, my BusinessService has a private string member called _userID as well as a method to set this _userID, this class looks like this:

public class BusinessService : IBusinessService
{
    private string _userID;

    public void SetUserID(string userID)
    {
        _userID = userID;
    }

    public void UpdateCustomer(Customer customer)
    {
        // update customer here.
    }
}

Because of the way the above class is written (since it isn't easy to have a custom custructor for WCF services in which I can just pass the userID,) then my web app is written like so:

public class WebApp
{
    private string _userID; // on page load this gets populated with user's id

    // other methods and properties

    public void btnUpdateCustomer_Click(object sender, EventArgs e)
    {
        Customer cust = new Customer();

        // fill cust with all the data.

        BusinessServiceClient svc = InstantiateWCFService();
        svc.UpdateCustomer(cust);
        svc.Close();
    }

    private BusinessServiceClient InstantiateWCFService()
    {
        BusinessServiceClient client = new BusinessServiceClient("EndPointName");
        client.SetUserID(_userID);
        return client;
    }
}

When looking at the data stored, nothing is saved for the user id.

Is there some form of design pattern, or feature that allows me to log who is making some change without having my service require the userID in every method call?

Community
  • 1
  • 1
IWriteApps
  • 973
  • 1
  • 13
  • 30

3 Answers3

0

You could use the InstanceContextMode property of the ServiceBehavior attribute to make the WCF service class per-session. (Note that this required wsHttpBinding or another session-aware binding.)

[ServiceBehavior(InstanceContextMode=InstanceContextMode.PerSession)]
public class BusinessService : IBusinessService

Then all you'd need to do is update your client code to use a single instance of the proxy class per session. A simple way to do that is to stash the proxy class in the Session object:

private BusinessServiceClient _client;

void Page_Init()
{
    if (Session["client"] == null) 
    {
        _client = InstantiateWCFService();
        Session["client"] = _client;
    }
    else
    {
        _client = (BusinessServiceClient) Session["client"];
    }
}

Now use the shared object _client instead of instantiating it every time. This way the session and _uid will be preserved, per session, on the service side.

McGarnagle
  • 101,349
  • 31
  • 229
  • 260
0

You can also add the userID in the message Header. See this link. This method was used in web services before WCF.

Community
  • 1
  • 1
Frank Goortani
  • 1,407
  • 17
  • 26
0

I know you are going to think this is extreme but has advantages

Authenticate with UserName and accept any password. And use sessions. This requires the user to pass a userID before they can do anything. And they don't need to send userID with every method call.

http://msdn.microsoft.com/en-us/library/ff648840.aspx

paparazzo
  • 44,497
  • 23
  • 105
  • 176