Hugoware

The product of a web developer with a little too much caffeine

Posts Tagged ‘Web.config

Making UserControls And Namespaces Work

with 2 comments

Adding UserControls inside of a Web Application project can tend to be a pain. You either have to register the control on each of the pages you want to use them in or add each name and path into the system.web/pages/controls section of your web.config. Neither of these are very convenient.

However, there is another option – Namespaces. Simply add an entry in the same location with values for the namespace, tagPrefix and assembly values and your control becomes ‘available’!

<configuration>
    <!-- snip -->
    <system.web>
        <pages>
            <controls>
                <!-- the assembly should be the same name as the 
                name generated by the application -->
                <add tagPrefix="site" namespace="WebApp.Controls" assembly="WebApp" />
            </controls>
        </pages>
    </system.web>
</configuration>

Now, everything appears like it is ready to go. If you start to type in your control name then you’ll see it pop up in the intellisense. However, if you run you application the control won’t appear!

If you pay close attention to the AppRelativeVirtualPath you’ll notice it stays null the whole time! To make matters worse is that even if you set the value manually it doesn’t make a difference – nothing shows up. You can try the Register information to add the control the page and you’ll see that the inline control works fine. It appears that you need that ‘src’ attribute before this works.

At this point we could give up and move on or we could get a little creative in our solution.

[Source Code] Normally, I’d drop a giant block of code in my post right here but from now on I’m going to start using github for my snippets. You can download the whole snippet at gist on github.

So to summarize our situation…

  • UserControls ‘work’ when added by namespace but they don’t actually appear in the page. (technically, the code still runs it just doesn’t show the .ascx content)
  • We can add UserControls to each page using the Register option but it isn’t nearly as convenient as the namespace.
  • We could add each UserControl to the web.config with the virtual path but it would require we update the web.config every time we change something.

I’ve wrestled with this a lot – I’ve tried the precompilation, I’ve tried ILMerge… I even tried kicking my laptop (which admittedly seemed to improve my code… too weird) – nothing seemed to work unless the virtual path to the ascx file was available. So instead of trying to solve the problem at build time I opted to solve it as soon as the program starts. Below is the code that I add to the Application_Start event in my Global.ascx file.

protected void Application_Start(object sender, EventArgs e) {
    UserControlScanner scanner = new UserControlScanner();
    scanner.ScanAndUpdate();
}

This code starts by finding all of the .ascx files in your site and all of the UserControl types (and sub types) loaded into the assemblies. It then uses this information to compare against the web.config file and add each control to the controls section.

What does it compare against? Well – first, it assumes that you added the namespace to your web.config file to begin with (otherwise, how else are you using it?) If the code finds a match between the UserControl namespace and a namespace in the web.config then it is added. It is worth noting that the prefix is determined by the the tagPrefix of the web.config entry of the matching namespace.

So below is a good example of what to expect.

<!-- Before code executes -->
<controls>
    <add tagPrefix="asp" namespace="System.Web.UI" assembly="System.Web.Extensions (snip)..." />
    <add tagPrefix="asp" namespace="System.Web.UI.WebControls" assembly="System.Web.Extensions (snip)..." />
    <add tagPrefix="site" namespace="WebApp.Controls" assembly="WebApp" />
</controls>

<!--After code executes-->
<controls>
    <add tagPrefix="asp" namespace="System.Web.UI" assembly="System.Web.Extensions (snip)..." />
    <add tagPrefix="asp" namespace="System.Web.UI.WebControls" assembly="System.Web.Extensions (snip)..." />
    <add tagPrefix="site" namespace="WebApp.Controls" assembly="WebApp" />
    <add tagPrefix="site" tagName="MyControl" src="~/Controls/MyControl.ascx" />
    <add tagPrefix="site" tagName="SomeOtherControl" src="~/Controls/SomeOtherControl.ascx" />
</controls>

Now, this does cause a bit of a problem… the site just loaded and the web.config just changed – Our updates aren’t available! To remedy that you’ll find this bit of code right after it finishes saving the changes.

//get the path to redirect to
string url = HttpContext.Current.Request.Url.AbsolutePath;

//then reset the system
HttpRuntime.UnloadAppDomain();

//and redirect the request to start over
HttpContext.Current.Response.Redirect(url);

So, if any changes are found then the site is reset and the user is redirected to the same requested the originally attempted to reach. Doesn’t seem like a big issue to me but it is something you want to keep in mind. Of course, if no changes are detected then the site isn’t reset and the code runs normally.

Now, if you add or remove controls, change paths then your web.config is automatically kept up to date and your application runs normally!

Advertisements

Written by hugoware

April 4, 2010 at 10:17 pm

Dude, For Real — Encrypt Your Web.Config

with 5 comments

After I released my web.config encryption utility I expected the world to transform into a Utopia of protected web.config files and happy developers. However, shortly after the tool was released I actually received some disagreement about the usefulness of web.config encryption.

Based on some other comments I received I got to thinking — I not sure that some people realize how possible it is to lose a web.config from a simple programming mistake.

But The Web.Config Is Safe — Right?

Sure, your web.config is safe by normal means. Just try it – find an ASP.NET website and just try to browse to their web.config file — See! it’s safe!!

True, your web.config is safe – but what about a programming mistake? Those never happen, do they? Are you sure?

One of my favorite examples is the file download. Sometimes we want to serve up content as if it is a download instead of showing it in the browser. That said, here is an ASP.NET MVC example of why you ought to go on ahead and encrypt that web.config file just to be on the safe side.

//MVC Action to download the correct file From our Content directory
public ActionResult GetFile(string name) {
    string path = this.Server.MapPath("~/Content/" + name);
    byte[] file = System.IO.File.ReadAllBytes(path);
    return this.File(file, "html/text");            
}

Seems reasonable enough – Other than error handling, do you see anything that looks out of place with this code? We map to the correct directory, we get the bytes for our file and return them to the visitor — You can even try it out.

/Home/GetFile?name=File.txt
bug-1

Cool, see how our file downloaded – Works great! But let’s be a little sneaky and play with the URL at the top. How about we do something like…

/Home/GetFile?name=../web.config

bug-2

Did you just get a sudden feeling of dread? Did you just shout ‘Oh Snap!’ loud enough that all your peers are staring at you? What do you suppose is in this file we just downloaded? I’ll give you three guesses, but I’m taking two of them away…

bug-3

It’s not hard to miss something — after all that’s why it’s a bug, because if we thought of it then it wouldn’t be there to begin with. Web.config encryption == cheap insurance.

Prying Eyes

I got this comment the other day and it was absolutely brilliant — Rob Thijssen wrote…

Encrypting configs in enterprise applications is definitely worth the time. Many companies allow contractors access to source code repositories that contain unencrypted configs that contain credentials which can be used to gain access to sensitive information. I have seen implementations where credentials were available to hundreds of developers that could give any one of them access to thousands of credit card details…

And he’s absolutely right. Do you want just anyone passing through the directory to have access to read the sensitive data inside your web.config? Just because they didn’t have hack into your server doesn’t mean they need to be reading the passwords to your SQL servers.

Dude, For Real — Just Do It

Web.config encryption only takes a couple moments and provides much more security than a clear-text file. It may not be enough to thwart a hacker that has full access to your entire server, but if you ever have that ‘uh oh — someone just downloaded my web.config’ moment, then at least you know you’re covered.

Written by hugoware

July 22, 2009 at 10:16 pm