Add css class attribute to html helpers in asp.NET MVC 2
August 26, 2010
It took me forever to find out how to do this so hoping this will save someone else the time.
Here is an example:
<%= Html.TextBoxFor(model => model.Email, new { @class = "txtLarge" })%>
In asp.NET MVC I used _class it seems in MVC 2 you need to use the @ symbol.
asp.net MVC 2 Validation – One Field Required
June 11, 2010
I was building a form that had two fields: home phone number and mobile phone number.
The client needed at least one of the two fields filled out.
Given the existing DataAnnotations nothing fit the bill in this case. I ended up creating a custom validation attribute that is applied at the class level.
I based it off of the PropertiesMustMatchAttribute custom attribute that is included in the AccountModels.cs/vb file within the default ASP.NET MVC 2 application project template (just do a File->New ASP.NET MVC 2 Web Project within VS 2010 and look for this class).
First off in the ContactModel.cs I added:
using System.ComponentModel.DataAnnotations; using System.Globalization;
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = true)]
public sealed class OneOrOtherFieldRequired : ValidationAttribute
{
private const string _defaultErrorMessage = "'{0}' or '{1}' are required.";
private readonly object _typeId = new object();
public OneOrOtherFieldRequired(string field1, string field2)
: base(_defaultErrorMessage)
{
Field1 = field1;
Field2 = field2;
}
public string Field1 { get; private set; }
public string Field2 { get; private set; }
public override object TypeId
{
get
{
return _typeId;
}
}
public override string FormatErrorMessage(string name)
{
return String.Format(CultureInfo.CurrentUICulture, ErrorMessageString, Field1, Field2);
}
public override bool IsValid(object value)
{
PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(value);
object field1 = properties.Find(Field1, true).GetValue(value);
object field2 = properties.Find(Field2, true).GetValue(value);
string valueAsString1 = field1 as string;
string valueAsString2 = field2 as string;
if (String.IsNullOrEmpty(valueAsString1) && String.IsNullOrEmpty(valueAsString2))
{
return false;
}
return true;
}
}
I then created in ContactModel.cs the ContactModel class. In this class I have among other properties the two phone number properies: HomePhoneNumber and MobilePhoneNumber.
[OneOrOtherFieldRequired("HomePhone", "MobilePhone", ErrorMessage="Please fill in either your home or mobile number.")]
public class ContactModel
{
...
public String HomePhone { get; set; }
public String MobilePhone { get; set; }
In the ContactController I have an action:
[HttpPost]
public ActionResult Index(Contact contact)
{
if (ModelState.IsValid)
{
contact.Store();
contact.SendEmail();
ViewData["ShowForm"] = false;
return View();
}
ViewData["ShowForm"] = true;
return View(contact);
}
When creating the view make sure to create a strongly typed view on the ContactModel
In the View I add the validation summary to display the error message if the requirement isn’t fulfilled.
<%= Html.ValidationSummary(true, "Please correct invalid and required fields.") %>
Create Excel file dynamically (Simple Way)
May 16, 2010
Scenerio: I’ve recently had a a few projects that I’ve created forms for. I have given the client a login to view all the form submissions, but in the end they want this data in an Excel file so they can easily manage it.
Research: I have found there a quite a few ways to achieve this. Some take advantage of the Excel interop, some create a .csv, some use third party tools, some use xml. Here is a good discussion I found on the topic at Stack Overflow, http://stackoverflow.com/questions/151005/create-excel-xls-and-xlsx-file-from-c.
All have pros and cons.
Solution: Here is what I have found to be the simplest way to read your dataset in an Excel file. First off, this doesn’t product a true Excel file, but it is something Excel can read into a table which often is all you need.
What I found is you can write the contents of a datagrid to an output stream that can be saved as a .xls file.
code snippet: I am using linq to bind to a datagrid
var registrations = from reg in db.Registrations
where reg.JumpPageId == int.Parse((String)e.CommandArgument)
orderby reg.TimeStamp descending
select reg;
HttpResponse response = HttpContext.Current.Response;
// first let's clean up the response.object
response.Clear();
response.Charset = "";
// set the response mime type for excel
response.ContentType = "application/vnd.ms-excel";
response.AddHeader("Content-Disposition", "attachment; filename=registrants.xls");
// create a string writer
using (StringWriter sw = new StringWriter())
{
using (HtmlTextWriter htw = new HtmlTextWriter(sw))
{
// instantiate a datagrid
DataGrid dg = new DataGrid();
dg.DataSource = registrations;
dg.DataBind();
dg.RenderControl(htw);
response.Write(sw.ToString());
response.End();
}
}
LIke I said, this doesn’t output a true Excel file so when you go to open it, you will be prompted a warning:
It is saying the contents of the file are in a different format than what the .xls extension says it is.
Click Yes and it will open.
If you were to open this file in a text editor you will see that it really is just the datagrid html output.
Not the most elegant solution but it is a quick way to throw an Export to Excel button on a report page.
My next blog post will show how to create an Excel file using a third party tool.
ASP.NET PostBackUrl not working on Server
April 2, 2010
Scenerio: I have a simple contact form in which I want to post to a different page.
Pretty simple, just set the PostBackUrl property of the button to the page I want to post to. It works like it should locally. When I deploy it to the server, Rackspace Cloud, it doesn’t work.
Research: After Binging for a while I found that the issue was due to a javascript error. If you VIew Source of the page, you’ll notice that the rendered html uses javascript to perform the PostBack.
<input style=”border-right-width: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px” id=”imgButton” class=”submit” onclick=”javascript:WebForm_DoPostBackWithOptions(new WebForm_PostBackOptions("imgButton", "", false, "", "/quick-contact.aspx", false, false))” src=”/i/qcsubmit.gif” type=”image” name=”imgButton” />
I then was able to capture the javascript error in IE. *Sidenote, what is a good way to do this? I ended up putting my cursor in the form, hit enter and quickly clicked on the browser stop button. There must be a better way.
![]()
“Webform_PostbackOptions” is undefined.
Ok…. Why is that? I found this in the comments at a blog post on http://pocketnerd.blogspot.com/2008/01/webformpostbackoptions-is-undefined.html
“I was getting this error in a load balanced production environment, but once the network admin turned on sticky sessions, all the errors went away. I assume it was trying to load the .axd file from the other web server and perhaps that caused a security problem which didn’t allow the file to load. Not sure but just thought I’d share what fixed it for me. “
I don’t have server access when hosting in the Cloud.
The WebForm_PostBackOptions function should be in the WebResource.axd file that you’ll see is referenced in the html on load.
<script src=”/WebResource.axd?d=Ttwk99ZBtJ8argpvGbO64g2&t=633750447951477990″ type=”text/javascript”></script>
I tried browsing to this file and this indeed was the issue, 404 Not Found.
Solution: I loaded the page locally. Viewed Source, grabbed the WebResource.axd and querystring, browsed to this file. This gave me the output of the javascript. I copied that all and placed it into a postbackfix.js file. I then referenced this js file on the page. Uploaded the new js and aspx files. Works now.
This took me a few hours of banging my head (not to Quit Riot) to figure out. Hope this helps someone else.
Feedback tab widget in ASP.NET
February 3, 2010
I recently had a client that wanted a Feedback tab that you find on a lot of sites now a days. Something similar to Get Satisfaction or uservoice.

I couldn’t find anything out there that I liked so here is what I came up with. The approach I am about to describe will place the Feedback tab on every page that is using your Master Page.
I am using the ASP.NET AJAX Control Toolkit for the modal.
First we need to set the modal up.
- Make sure you have the AjaxControlToolkit assembly in your project references.
- Add the page directive for the Control Kit at the top of your Master Page:
<%@ Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit" TagPrefix="ajaxToolkit" %>
- Add the ScriptManager to your Master Page:
<asp:ScriptManager ID="ScriptManager1" runat="server" />
- Place the Feedback tab on your site by adding it as an ASP.NET ImageButton and adding a cssclass to it:
<asp:ImageButton ID="lbFeedback" CssClass="tab" runat="server" ImageUrl="images/feedback.gif" />
- Add this styling to your css stylesheet:
.tab{position: fixed; right: 0; top: 250px;}This will position the tab on the right of the browser window.
- Now add the Feedback form inside a panel that will appear in the modal to the bottom of your Master Page just before the </form>.
<asp:Panel ID="pnlModal" runat="server" CssClass="modal"> <p>Thank you for taking the time to leave us feedback. Good or bad we want to know how your experience was at our establishment.</p> <p><label>Name:</label><br /><asp:TextBox ID="txtName" runat="server" /></p> <p><label>Email:</label><br /><asp:TextBox ID="txtEmail" runat="server" /></p> <p><label>Message:</label><br /><asp:TextBox ID="txtMessage" runat="server" TextMode="MultiLine" Columns="40" Rows="10" /></p> <asp:Button ID="btnSubmit" runat="server" Text="Submit" onclick="btnSubmit_Click" /> <asp:Button ID="btnCancel" runat="server" Text="Cancel" /> </asp:Panel> - Add the Modal Popup Extender control to handle the modal:
<ajaxToolkit:ModalPopupExtender ID="mpe" runat="server" TargetControlID="lbFeedback" PopupControlID="pnlModal" BackgroundCssClass="modalbg" CancelControlID="btnCancel"></ajaxToolkit:ModalPopupExtender>
- Lets add a Thank you message that is only visible after the feedback form is submitted. I add this at the top of the Master Page:
<div id="thankyou" runat="server" visible="false" class="thankyoumessage">Thank you for leaving feedback</div>
We now have a non-functioning Feedback form appearing inside a modal when the Feedback tab is clicked. A cancel button is there if they decide not too leave feedback after all.
By adding the ASP.NET Button control in the modal it will do a PostBack back to the page that can be handled in the Master Page’s code-behind. In the button handler I add the logic to simply email the submitted form to a desired email. See my previous post on how to do that.
![]()
At the end of the Submit Button handler I have a Page Redirect that sends the visitor back to the page they are on. Two reasons for this:
- In the redirect I pass a QueryString param to the page letting it know that Feedback has been submitted. In the PageLoad of the Master Page I check for this param and if it is present display a Thank You at the top of the page.
- Secondly I do a redirect so the visitor won’t do a refresh to get ride of the Thank You message, thus re-sending the feedback info again.
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack && !String.IsNullOrEmpty(Request.QueryString["fb"]))
{
// the feedback form has been filled out, display a thank you message.
thankyou.Visible = true;
}
}
/// <summary>
/// Handle the feedback form submit
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void btnSubmit_Click(object sender, EventArgs e)
{
// add the logic to handle the submited form fields
string currentPage = Request.Path;
Response.Redirect(currentPage + "?fb=1");
}
To sharpen it up a bit some final touches in the style sheet for the modal and the thank you message:
.thankyoumessage{background-color:#cc0000; color:#fff; padding:20px; font-size:3em; text-align:center}
.modal{background-color:#fff; border:solid 3px gray; padding:8px; width:350px; height:450px;}
.modalbg{filter: Alpha(Opacity=70); -moz-opacity:0.7; opacity: 0.7; width: 100%; height: 100%; background-color: #000000; position: absolute; z-index: 500; top: 0px; left: 0px;}
I’ve put together a simple example website with all this working for download here.
There certainly is more that can be added upon this such as making the thank you message only visible for 3 seconds. But, I think this is a good foundation.
-
Categories
- asp.net (11)
- Blog (1)
- Business (5)
- Conferences (1)
- Errors (3)
- Portfolio (2)
- Reviews (2)
- SQL Server (3)
- Tips (1)
- Uncategorized (1)
- Web Development (13)
-
Archives