ASP.NET MultiLine TextBox MaxLength Validation

There have been many articles and forums addressing the fact that the MaxLength property of the ASP.NET TextBox does not work when you set TextMode to MultiLine. The majority of these solutions use the KeyPress and OnBlur events. This brings with it lots of JavaScript and a host of browser issues. I was impressed by the RegularExpressionValidator options because they can tie in to the AJAX ValidatorCalloutExtender. I also like the server-side validation that you get with the native validation controls.

The solution I settled on is a combination of all the above. I use an ASP.NET RegularExpressionValidator on the MultiLine TextBox. The code looks like this:

<asp:TextBox runat="server" ID="txtDescription" TextMode="MultiLine" Rows="5" Width="300" />
<
asp:RegularExpressionValidator runat="server" ID="revtxtDescription" ControlToValidate="txtDescription" ErrorMessage="Exceeds 500 character maximum." ValidationExpression="^[\s\S]{0,500}$" Display="None" />
<
ajax:ValidatorCalloutExtender ID="vcerevtxtDescription" runat="server" TargetControlID="revtxtDescription" />

Good so far, but to quote Mark Hildreth:

“I agree that that works for preventing users from posting too much text, however it does’t prevent them from typing more than 500 characters into the box. The validators only perform their validation in the onchange event which is not triggered on every key stroke. Imagine your dismay if you spent 10 minutes typing into a textbox, only to have the form say you have exceeded the 500 character limit?”

The JavaScript below will call this RegularExpressionValidator every second. I find that it does not noticeably slow down the form.

<script type="text/javascript">

    $(document).ready(function () {
        setInterval("validateDescription();", 1000);
    });

    function validateDescription() {
        var myValidator = document.getElementById("<%= revtxtDescription.ClientID %>");
        ValidatorValidate(myValidator);
    }

</script>

Now as the user is typing, they will be warned within one second of exceeding 500 characters. If they paste into the textbox, it will alert them too.

Entity Framework Filter Child Entity

I was looking for a way to filter child entities with eager loading. I ran into this useful blog post by Beth Massi on the subject.

Here is the code I ended up using. It doesn’t work with server-side paging, but I didn’t need it in this case.

Dim query = (From x In db.OrderChecklistItems Where x.Enabled = True Select OCI = x, _
             
OD = From y In x.OrderDocuments Where y.OrderID = OrderID)

Dim customers = From item In query.ToList Select item.OCI

GridView1.DataSource = customers

Entity Framework GridView RowDataBound

I found it tricky to get actual entities in the GridView RowDataBound event.

Per Diego Vega’s post here, this may only happen because I am using the EntitySetName property of the EntityDataSource.

    Protected Sub GridView1_RowDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles GridView1.RowDataBound
If e.Row.RowType = DataControlRowType.DataRow Then
            Dim descriptor As ComponentModel.ICustomTypeDescriptor = e.Row.DataItem

If descriptor IsNot Nothing Then
                Dim prop = descriptor.GetProperties().Cast(Of ComponentModel.PropertyDescriptor)().First()

Dim Order As Order = DirectCast(descriptor.GetPropertyOwner(prop), Order)

Response.Write(“Order Number:” & Order.OrderNumber)
End If
End If
End Sub

GridView Row Index in Markup

Sometimes I want to show the e.Row.RowIndex of a GridViewRow in the markup of the page. I don’t want to hook into the RowDataBound method just to display a simple number. The answer varies for GridViews and Repeaters. Click here for the complete rundown.

GridView:

<asp:Literal runat="server" Text='<%# Container.DataItemIndex + 1 %>' />

Repeater:

<asp:Literal runat="server" Text='<%# Container.ItemIndex + 1 %>' />