Dynamically modifying client endpoints in WCF

I was doing some contract work for a client building out a SOA backend for them. It consisted of some WCF services that all talked to one another. Due to how the client had set up their deployment process, we had to dynamically load these client endpoint address from an external XML file at runtime, instead of setting them inside the web.config.
In other words, we needed a way to dynamically change the address attribute:

        <endpoint address="http://someaddress.com/webservice"
          binding="ws2007HttpBinding" bindingConfiguration="WebService_ws2007HttpBinding"
          contract="WebService.ServiceContracts.IWebService" name="ws2007HttpBinding_IWebService" /> 

WCF allows you to programmatically configure any System.ServiceModel setting in the web.config, so the challenge was to inject the endpoint before the call was actually made. Normally, you can pass in the endpoint address to the channel factory constructor and be done with it. However, the service in question we needed to modify was a simple passthrough WCF router. There was no code to speak of, so in order to modify the client endpoints we decided to do so in a service behavior.

The first task was to figure out how to access the endpoints themselves. At first, I tried:

    var serviceModelSection = ConfigurationManager.GetSection("system.serviceModel"); 
    ClientSection clientSection = serviceModelSection.GetSection("client" ) as ClientSection;
    ChannelEndpointElementCollection endpointCollection = clientSection.Endpoints;

However, when I actually tried to edit the endpoints inside ChannelEndpointElementCollection, I got an error: “The configuration is read only”. After searching online, I tried using WebConfigurationManager.OpenWebConfiguration instead:

       Configuration webConfig = WebConfigurationManager.OpenWebConfiguration("~" );
       ClientSection clientSection = webConfig.GetSection("system.serviceModel/client" ) as ClientSection;
       ChannelEndpointElementCollection endpointCollection = clientSection.Endpoints;

       //dynamically load the URI here
       Uri serviceAddress = “http://sometempuri.org”;

       endpointCollection[0].Address = new EndpointAddress(serviceAddress);         

This option was a non starter because webConfig.Save() literally saves the actual web.config file itself. This causes the application pool to recycle, and since it edits the physical file, the changes made won’t apply to the current request.

Ultimately, we ended up implementing IEndpointBehavior interface. The IEndpointBehavior interface has an ApplyClientBehavior method, that takes as its parameter a client service endpoint. This method fires only once for the lifetime of the application for each client endpoint defined, which is exactly what we wanted. The following sample code demonstrates how this service behavior can be used to dynamically set the EndpointAddress for the client endpoint.

public class WebServiceEndpointBehavior : IEndpointBehavior
    public void Validate(ServiceEndpoint endpoint)

    public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)

    public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)

    public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
        Uri serviceAddress = new Uri("http://sometempuri.org ");   //dynamically load URL here
            endpoint.Address = new EndpointAddress(serviceAddress);       

From here, it was just a matter of coding the behavior extension element that loads the behavior, as well wiring in this extension element into the web.config. Here are the relevant snippets:

namespace WebService
    public class WebServiceEndpointBehaviorExtensionElement: BehaviorExtensionElement
        protected override object CreateBehavior()
            return new WebServiceEndpointBehavior ();

        public override Type BehaviorType
            get { return typeof (WebServiceEndpointBehavior ); }
        <behavior name="updateEndpointAddress">
        <add name="webserviceEndpointBehavior" type="WebService.WebServiceEndpointBehaviorExtensionElement, WebService" />

CredentialCache.DefaultNetworkCredentials is empty and so is Thread.CurrentPrincipal.Identity.Name

I was working on a simple console application in C# that issued HTTP DELETE requests to WebDAV to delete expired documents from the file system. Once completed, this was to run periodically as a job. However, I kept getting back 401 Unauthorized on the DELETE requests. While troubleshooting the issue, I went down the rabbit hole and learned some interesting things. I was passing in CredentialCache.DefaultNetworkCredentials as my HttpRequest credentials. So as a sanity check, I tried viewing it in the debugger to make sure the program was passing in my credentials, only to find that CredentialCache.DefaultNetworkCredentials.UserName was blank.

Well, it turns out that you can’t actually view the credentials unless you set them manually yourself. According to the MSDN documentation:

“The ICredentials instance returned by DefaultCredentials cannot be used to view the user name, password, or domain of the current security context.”

So I tried checking the value of Thread.CurrentPrincipal.Identity.Name instead. This was blank as well. Upon further reading, I determined that this was due to the principal policy not being explicitly set to WindowsPrincipal. Once I did so, Thread.CurrentPrincipal.Identity.Name correctly displayed my windows login ID:


It is helpful to review what an application domain is before proceeding. In Windows, every application runs as its own process, complete with its own set of resources. By isolating applications via processes, this minimizes the risk that one badly coded application can negatively impact others. In the Common Language Runtime, application domains provide an even more granular level of isolation. A single process (the application host) can run multiple application domains, each with the same level of isolation that separate processes would have, minus any of the overhead.
Because every app domain is separate from one another, each has its own Principal object. This object represents the current security context that the code is running as. The PrincipalPolicy is an enum that indicates how this principal object is to be created for the given app domain. Setting it to WindowsPrincipal will map the principal object to the Windows user that the application host is executing as. By default, the PrincipalPolicy will be UnauthenticatedPrincipal, which will set Name to empty string.

After doing some more digging, I also found out that I could use WindowsIdentity.GetCurrent().Name to determine what user the program was executing as:


Having finally proven to myself that my program was running as the correct user, I eventually figured out the issue. It was completely unrelated to the code of course; I had simply forgotten to enable Windows Authentication in IIS. I didn’t mind the time sink, as it proved to be quite educational.

A no frills AJAX uploader using ASP.NET and vanilla javascript

This is a tutorial on how to write a simple AJAX uploader. I’ve been doing more front end development at work lately, and I recently needed to write a page that processed a small file upload from the user. Because the page in question only accepted files up to 1 MB in size, I figured it would be a much better user experience to do the upload via AJAX, rather than forcing the user to sit through an entire FORM post and wait for the page to reload. Normally, I’d consider going with a third party solution, as there are quite a few AJAX uploaders available on the web. However, management wanted to reduce dependencies on third party code. This sounded reasonable to me. The files in question were going to be small, so fancy features such as progress bars that are commonly found in AJAX uploader plugins would prove to be unnecessary anyway. As a bonus, I’d get to avoid the hassle of researching all the available options out there and save time spent reading through pages of boring documentation. All in all, I was pretty happy to go through the exercise of writing my own.

The first roadblock that I encountered is the fact that Javascript can’t actually access the file system. To see why this would be a bad idea, just look at the well intentioned yet completely awful technology that is ActiveX and all the horrible malware that it has spawned. Giving a client side scripting language like Javascript access to the file system represents a gaping security hole, so it is a good thing that it cannot. To work around this limitation, we must still do a FORM post, but through the use of some clever smoke and mirrors the user never needs to leave the page.

This is accomplished using the “target” attribute of the form element. This attribute specifies where to open the page specified by the “action” attribute. For example, you can provide the value “_blank” to tell the browser to open up the “action” page in a new window. It just so happens that you can also specify an Iframe for your target attribute. So the solution will be to add a hidden IFrame element to the HTML and then specifying it as the target attribute of the form.

The HTML is straightforward. We will have a form element, a file upload element, a hidden IFrame, and a submit button. Finally, we will have a div (with the display initialized to “none”) that displays a simple “upload in progress” message along with an animated gif of a spinning wheel.

<form id="uploadForm" action="/processupload.aspx" method="post" enctype="multipart/form-data" target="upload_target" onsubmit="startUpload();"> 	  
	<input type="file" name="picFile" runat="server" size="50">                        
	<input type="submit" name="submitBtn" value="Upload">						
<br />  
<div id="result" style="display:none">Upload in progress.... please wait <img src="/images/processing_small.gif" align="absmiddle" /></div>
<iframe id="upload_target" name="upload_target" style="width:0;height:0;border:0px solid #fff;"></iframe> 

The Javascript code is fairly simple as well. We will have two simple functions: StartUpload and StopUpload. StartUpload will simply display our hidden div:

function startUpload() {
	$('result').style.display = "block";

StopUpload will be called after the server has finished processing the upload. It will either display “Upload successful” or show some error message.

function stopUpload(success) {
    var result = '';
    if (success == 1) {
        $('result').innerHTML = 'The file was uploaded successfully!';
    else {
        $('result').innerHTML = 'Sorry, there was an error during the file upload.';

The final piece of the puzzle is to figure out a mechanism with which to call StopUpload after the server has finished processing the upload. Because the “target” attribute is an iframe, we can write javascript code in the server response, which will then automatically be called when the browser renders the result in the IFrame.

The following is a bare bones Page_Load() function for the processUpload.aspx specified in the form action. Obviously, a real world version would contain more robust error handling, security checks, business logic, and so on. It’d also have a more descriptive file name as well.

protected void Page_Load(object sender, EventArgs e)
    int success = 0;
	HttpPostedFile uploadedFile = Request.Files[0];

        //In the real world we'd want to pull set the upload path from web.config or something along those lines
        string imageUploadPath = "C:\\temp";  

        string iframeJavascript = "<script language="javascript" type="text/javascript" >window.top.window.stopUpload(1)</script>";
    catch (Exception e)
        //here is where we could send back more detailed error information to the browser...
        string errorResponse= "<script language="javascript" type="text/javascript" >window.top.window.stopUpload(0)</script>"; 

Lo and behold, we now have a fully functional AJAX uploader. From here we can make any number of improvements to make it more useful. For example, if we wanted StopUpload to display a more useful error message, we could add an “ErrorMessage” parameter to the javascript function, and have the server write out appropiate messages based on the nature of the error: “File size too large”, “Error processing file”, and so on. Of course, if you find yourself spending too much time implementing, testing, and debugging additional functionality, it would make more sense to use the many AJAX uploader plugins already out there on the internet (many of them free).