Wednesday, September 19, 2012

Handle regular html controls in ASP.NET Webforms

By "handle regular html controls in .NET" I mean handling values of non-ASP.NET controls, nor html server controls after a postback. Basically an input control with no runat="server" attribute. Why on earth would one do such a thing? Well, recently I was working on a project where input fields could be added kinda indefinitely in a certain form. The fields were added to the form by using javascript and templates. We preferred that over a postback per added field.

So, in our html template we had something like this:
<input id="MyRegularTextBox_" name="MyRegularTextBox_" type="text" value="" />

This was added to a container div and a counter was added to the id and name of the input field. In the end, a form could look like this when it was posted back to the server:
<input id="MyRegularTextBox_1" name="MyRegularTextBox_1" type="text" value="" />
<input id="MyRegularTextBox_2" name="MyRegularTextBox_2" type="text" value="" />
<input id="MyRegularTextBox_3" name="MyRegularTextBox_3" type="text" value="" />

As ASP.NET doesn't know about these fields, we need another way to access the values of those added field. In fact, if you are from the old asp era or know some php or the like, it's pretty obvious. You just need to loop over all the keys in the Request.Form object. Combine that with a LINQ expression and we have a winner!
foreach (string key in Request.Form.AllKeys.Where(x => x.StartsWith("MyRegularTextBox_")))
{
    string myRegularTextBoxValue = Request.Form[key];

    // Do some great stuff!
}

The same logic can also be applied for file uploads. Instead of looping over the Request.Form keys, you need to loop the Request.Files collection. However, one important thing to do is setting the encoding type of the form.
The html looks like this:
<input type="file" id="attachment_1" name="attachment_1" />

Code behind like this:
protected override void OnLoad(EventArgs e)
{
    base.OnLoad(e);

    // The form must handle file uploads (with regular html, non-asp.net, controls)
    Page.Form.Enctype = "multipart/form-data";
}

foreach (string key in Request.Files)
{
    HttpPostedFile postedFile = this.files[key];
}

Et voilĂ , you're set to go!