Posts Tagged '.NET'

Validating That At Least One TextBox Has Content

I came across an interesting little validation problem on my current project. The site is for members only – and in order to become a member, you need to be nominated. You can provide either one or two nominators, but you must provide at least one.

So how to force users to enter text in either of two TextBoxes? RequiredFieldValidators won’t do, because either one can be left empty. Yet at least one must be completed. Clearly this is a job for CustomValidators.

The client-side and server-side code are both fairly straight-forward, but I thought someone out there might find it useful, so here it is.

First of all, the CustomValidators in the ASPX page:


<asp:CustomValidator ID=”Nomination1CustomValidator” runat=”server” Display=”None” ValidateEmptyText=”true” ClientValidationFunction=”CheckNominations” ErrorMessage=”At least one nomination must be provided” ControlToValidate=”Nominated1TextBox” OnServerValidate=”Nomination2CustomValidator_ServerValidate”></asp:CustomValidator>


<asp:CustomValidator ID=”Nomination2CustomValidator” runat=”server” Display=”None” ValidateEmptyText=”true” ClientValidationFunction=”CheckNominations” ErrorMessage=”” ControlToValidate=”Nominated2TextBox” OnServerValidate=”Nomination2CustomValidator_ServerValidate”></asp:CustomValidator>

Note the empty ErrorMessage in the second validator. Combined with display=”none’, that means our ValidationSummary control is only going to display one error message to the user, making it much less confusing. Also notice that ValidateEmptyText is set to true – otherwise, our code will never run.

Then the JavaScript. We’re validating two controls, so even though we use the standard signature the validators are expecting, we’re only interested in the args. I set the TextBoxes’ ClientIDMode to static and used jQuery to get the controls.  (I use jQuery for pretty much all my client-side code).

function CheckNominations(sender, args) {
  if ($(‘#Nominated1TextBox’).val() == “”
      && $(‘#Nominated2TextBox’).val() == “”) {
        args.IsValid = false;
  }
   else {
args.IsValid = true;

   }

}

And, of course, we also need to implement the server-side code for a complete solution:

If String.IsNullOrEmpty(Me.Nominated1TextBox.Text) And
String.IsNullOrEmpty(Me.Nominated2TextBox.Text) Then
        args.IsValid = False
Else
        args.IsValid = True
End If

So now the user must fill in one of the TextBoxes, but can pick either one.  I have been using ASP.NET MVC a lot recently, and it’s nice to go back to Web Forms and see how very easy it is to take built-in controls like the custom validator and use them to meet your specific needs.

Kevin Rattan

For related information, check out these courses from Learning Tree:

Building Web Applications with ASP.NET and Ajax

jQuery: A Comprehensive Hands-On Introduction

Visual Studio Tips – Wildcard Search and Replace

Ever wanted to do a wildcard Search and Replace in Visual Studio? I don’t just mean finding things using wildcards, but selectively replacing part of what you find while leaving other parts untouched. I came across an example recently where I needed to do just that – and since what I discovered saved me an inordinate amount of work, I thought I’d share it with you.

I was asked to look over the code for an ASP.NET Web Forms web site with a Sql Server back end. When I looked into the code, however, I discovered that the database was actually MySql… which I don’t support. I managed to migrate the database over to Sql Server, but then found that although the project used NHibernate, much of the data access code was written as inline SQL in the code-behind pages. And that code wouldn’t work with Sql Server.

The problem was primarily lots of code along these lines:

      rs.GetString(“ColumnName”)

Unfortunately, this code errors with the Sql Server driver because GetString() only accepts integers. I needed to keep the variable name, but change the code so that it was something like this:

     rs[“ColumnName”].ToString();

And there were a huge number of column names and GetXXX() methods that needed changing.

So I did a little research, and discovered that there’s an option to use regular expressions in the Find and Replace dialog.

find options in find and replace dialog

Crucially, you can use Regular Expressions for both find and replace. So I was able to enter the following find string:

   rs.GetString\(“{.@}”\);

and the following replace string:

   rs[“\1”].ToString();

And change all the GetStrings() for all of the columns in one simple Find and Replace – thus avoiding a great deal of tedious and repetitive work.  Here’s hoping I’ve saved you some of the same.

Kevin Rattan

For other related information, check out these courses from Learning Tree:

Building Web Applications with ASP.NET MVC

Building Web Applications with ASP.NET and Ajax

Amazon Web Services Tools For Visual Studio

Recently I’ve been needing to make a few tweaks to the hosting for my cocktailsrus project. It’s hosted on Amazon EC2, and until now I have been logging on to the Amazon console whenever I need to make changes. That’s not a great hardship, as it is (unsurprisingly) a well constructured and user friendly interface.

But it turns out there’s a better way. Amazon have created a set of tools that integrate with Visual Studio. They make it easy to manage your instances directly through Visual Studio.

The tools give you a new set of project templates for working with Amazon Web Services (including EC2):

project templates dialog

And you also get a new set of tools for managing your instances. The AWS Explorer window is available via View | AWS Explorer.

View drop down

When you open it, you need to select the account and region you want to manage:

.account and region dropdowns

These only become available after you’ve clicked on the Add Account icon (highlighted in red above). The icon brings up a dialog allowing you to enter your credentials. If you don’t know your secret key, you can get it via the AWS console.

credentials dialog

Once you’ve completed the form, you can manage your instances (including security groups etc.) directly from inside Visual Studio.

Here’s the big picture view of a management screen:

Visual Studio with tools

And here’s a close up (with a few details snipped out for obvious reasons):

detail of Visual Studio tools

The toolkit integrates with both 2008 and 2010, and allows you to manage AWS through a familiar user-friendly Visual Studio interface – and without having to log on to the console every time you want to make a change.

Kevin Rattan

For other related information, check out these courses from Learning Tree:

Cloud Computing Technologies: A Comprehensive Hands-On Introduction

Cloud Computing with Amazon Web Services

Precompiling LINQ Queries in .NET Framework 4.5

While it is possible to precompile LINQ queries for Entity Framework either to have your queries run faster (either without parameters or with parameters) or to run your queries on a background thread, in .NET Framework 3.5/4, it’s neither pretty nor fun. The code isn’t particularly ugly but it does require some additional effort for you to have your queries precompiled. Unless you want to run your statement on a background thread, you’ll only benefit from precompiling if you execute the same LINQ statement many times (and, even then, if your queries aren’t very complex then you still may not get much benefit).

However, there is some benefit from precompiling and it would be nice to have it, provided you didn’t have to do any extra work. That’s where .NET Framework 4.5 steps in. While it’s always dangerous to talk about what’s supposed to be in an upcoming version of some software, the intent is for the framework to recycle your compiled LINQ queries (a feature called “auto-compiled LINQ queries”). Every time a LINQ statement is issued, the framework will build the statement’s expression tree (the first step in the compilation process) and generate a unique identifier for the statement. The framework will then search a cache to see if that identifier is already present. If the framework doesn’t find the identifier, the framework finishes the compilation process and adds the compiled version of the statement to the cache before executing it; if the framework finds the identifier, it uses the already compiled version of the statement.

Notice what’s happening here: You still have to pay for the statement’s expression tree to be generated but, once you’ve paid that cost, if your statement or one very much like it already exists in the cache then all subsequent compile steps are skipped and your statement is just executed. If you have the identical LINQ statement in several places in your application then there’s no need—from an efficiency point of view—to rewrite your application to have that LINQ statement appear only once. The cache will store only one version of the statement and use it from all the places it appears in your application (of course, you’d want to have a good reason for scattering an identical LINQ expression throughout your code). As an added benefit, statements are only compiled if they are used. The older precompile method meant that you could precompile a LINQ statement that you might never use.

You don’t have access to the compiled queries in the cache (at least, not yet) so you’ll need to continue using CompiledQuery if you want to execute your LINQ statement on a background thread.

Turning Off Auto-Compile

If you don’t want to have your statements precompiled, you can turn the feature off by setting the DefaultQueryPlanCachingSetting on the ObjectContext’s ContextOptions property to false, like this:

oc.ContextOptions.DefaultQueryPlanCachingSetting = false;

I can only see two scenarios when turning off this option would be a good thing. Turning off auto-compile would eliminate whatever cost is involved in generating the identifier and walking the cache but, I’m willing to assume, that will be more than offset by not compiling a LINQ statement more than once. If you have a LINQ statement which is only executed once (and, furthermore, if this is true of all the LINQ statements associated with this instance of the ObjectContext) then setting this option to false would probably be a good choice. In this scenario, there’s also no benefit in using the CompiledQuery class to precompile your queries.

The second scenario involves sticking with the CompiledQuery class. Because there is a cost associated with maintaining and searching the cache, using the CompiledQuery class should give you better performance than the auto-compile option—no need to generate an identifier or maintain the cache (provided, of course, you don’t precompile statements you never use). If you’re obsessed with performance and don’t mind the extra work (or are paid by the hour) you could stick with the CompiledQuery class, even in .NET Framework 4.5. In this scenario, you may need to turn off DefaultQueryPlanCachingSetting to prevent the framework from also maintaining its cache of auto-compiled statements.

One last note: This does mean that if you’re using the CompiledQuery class in your existing code then, when you upgrade to .NET Framework 4.5, you’ll actually be getting better performance than the programmers who count on the framework’s default behaviour.

Peter Vogel

Calling LINQ Queries in the Background

In my last two posts (here and here), I showed how you can pre-compile a LINQ query to improve your performance. As I noted in those posts, I wouldn’t expect a blinding improvement in response times—your application probably doesn’t have many really complex queries and, as a result, probably doesn’t spend a lot of time converting LINQ into SQL.

What I didn’t say explicitly is that what the pre-compile process does is generate a delegate—which means that, once you’ve pre-compiled your LINQ statement, you can call it asynchronously, as you would with any other delegate. If you have a long running query, you might prefer to have your LINQ statement execute asynchronously so that your user interface isn’t tied up while you wait for results to be returned (or so your application can go and do something else). While simply pre-compiling your LINQ statements won’t save you a lot of time, running your statements asynchronously is a change that could give you a more responsive application.

Assuming you’re familiar with the material in the previous posts, at this point you’ll have a variable called qry that holds a reference to a pre-compiled LINQ statement. To execute the LINQ statement and catch its results (a collection of Northwind Order objects for a specific customer), you’d call the compiled query’s Invoke method, passing whatever parameters are required. For my example, which requires the LINQ statement to be passed its ObjectContect and a customer Id, that code looks like this:

Dim oc As New northwndModel.northwndEntities

Dim res = qry.Invoke(oc, “ALFKI”)

For Each ord inres

The problem here is that, even with the SQL statement already generated, you still have to wait for Entity Framework to open a connection to the database, send the SQL, wait for the data to be retrieved, and (finally) for the database connection to be closed. Your application could be doing something else if you executed the statement asynchronously.

Executing Asynchronously

To execute your LINQ statement asynchronously, you call the BeginInvoke method on the variable holding the compiled statement instead of using the Invoke method. The parameters passed to the BeginInvoke method are the same as those passed to the Invoke method with the addition of parameter specifying a method to call when the LINQ query completes (and a fourth parameter set to Nothing).

This example, for instance, specifies that the method ProcessOrders is to be called automatically when the LINQ statement completes:

qry.BeginInvoke(en2, “ALKFI”, AddressOf ProcessOrders, Nothing)

The ProcessOrders method must accept as its only parameter an IAsyncResult object. To retrieve the result of the LINQ statement, you call the EndInvoke method on the variable holding your compiled LINQ query, passing that IAsyncResult object. The EndInvoke method will return the result of your LINQ query. This example extracts the collection of Orders generated by the LINQ statement:

Public Sub ProcessOrders(iar As IAsyncResult)
Dim ords = qry.EndInvoke(iar)

End Sub

A LINQ statement is “lazy loaded”—the actual data isn’t retrieved until you process the results from the LINQ statement. You should probably alter the lambda expression holding your LINQ statement to ensure that the data is retrieved on the background thread. You can do that by converting the results of your compiled statement into a List before returning it. If you’re doing that conversion, you should change the data type of the final data type passed to the Compile method since it represents the type being return from the expression:

Dim qry = System.Data.Objects.CompiledQuery.Compile(
Of northwndModel.northwndEntities,

String,

List(Of northwndModel.Order)) _
(Function(en, custid)
(From o In en.Orders
Where o.CustomerID = custid

Select o).ToList)

There are trade-offs to be made here. If, for instance, you only process some of the Orders retrieved by this statement then whatever benefits you may gain by running asynchronously may be lost by retrieving too much data.

I mentioned in my last post which Learning Tree course had the best coverage of LINQ. I should also have mentioned the course that I think does the best job on Entity Framework: Learning Tree’s Design Patterns and Best Practices. A course, by the way, that I think every .NET developer should take.

Peter Vogel

PreCompiling LINQ Queries with Parameters

In my last post, I looked at precompiling a LINQ query to speed up (at least a little bit) your application. The LINQ statement I used as my example was very simple:

Dim res = From o In en.Orders
          Select o

This post looks at a more realistic example: a LINQ statement that has a Where clause. But I’ll also look at how to declare the variable holding the precompiled LINQ statement so that you can put your compiled statement to good use.

In my last post, I created a LINQ statement that had to be passed only the ObjectContext that it would use. In real life, most LINQ statements will require more than that to be passed to them. For instance, this LINQ statement retrieves only the orders for the customer number that’s specified in the variable called “custID”:

Dim res = From o In en.Orders
          Where o.CustomerID = custId
          Select o

Effectively, that custId variable is a parameter that must be passed to the pre-compiled LINQ statement when the statement is executed.

If your statement does require parameters then, when compiling it, you must specify the parameter in two places:

  • In the data type list used by the Compile method: You must specify the data type of the parameter
  • In the parameter list for the lambda function: You must specify the name that will be used in the LINQ query to refer to the parameter

Enhancing the Compile method example from my last post to precompile my Where-clause query to accept the custId string parameter gives this code:

Dim qry = System.Data.Objects.CompiledQuery.Compile(
                    Of northwndModel.northwndEntities,
                    String,
                    IQueryable(Of northwndModel.Order)) _
(Function(en, custid) From o In en.Orders
                                Where o.CustomerID = custid
                                Select o)

Calling the LINQ statement and passing both parameters (the ObjectContext and a customer Id) would look like this:

Dim oc As New northwndModel.northwndEntities
Dim res = qry.Invoke(oc, “ALFKI”)

For this technique to be useful, though, you’ll want to set the qry variable to the precompiled query at the start of your application and then invoke the query some other method (or in several other methods). As a result, you’ll probably want to declare the variable holding the compiled query outside of any method. You must declare the variable using the Func type—another generic type that must be told what data types it’s working with. Fortunately, you can just copy declaration you passed to the Compile method to define the qry variable.

For the last example with the string parameter, the declaration of the qry variable would look like this:

Dim qry As Func(Of northwndModel.northwndEntities,
                String,
                IQueryable(Of northwndModel.Order))

Now, at the start of your application you can compile your LINQ statements into a set of variables and, later in your application, use the variable’s Inovke method to execute the statement.

Peter Vogel


Learning Tree International

.NET & Visual Studio Courses

Learning Tree offers over 210 IT training and Management courses, including a full curriculum of .NET training courses.

Free White Papers

Questions on current IT or Management topics? Access our Complete Online Resource Library of over 65 White Papers, Articles and Podcasts

Enter your email address to subscribe to this blog and receive notifications of new posts by e-mail.

Join 29 other followers

Follow Learning Tree on Twitter

Archives

Do you need a customized .NET training solution delivered at your facility?

Last year Learning Tree held nearly 2,500 on-site training events worldwide. To find out more about hosting one at your location, click here for a free consultation.
Live, online training

%d bloggers like this: