Jack @ ASP.NET

As a software engineer, I focus on .NET, especially asp.net, C#, WCF and so on, and I am also very interested in Search Engine Optimization.

Entries for the ‘.Net’ Category

Call SQLCMD to run SQL script via C#

Usually, we need to call some sql script to update our database in our application(C#), and it is a good way to call SQLCMD to execute the sql scripts. One important reason is that our scripts always contains the GO statement which is is not a Transact-SQL statement; it is a command recognized by the sqlcmd and osql utilities and SQL Server Management Studio Code editor. Since the SQLCMD and SQL Server Management Studio will do the same thing, the scripts edited by SQL Server Management Studio will be 100% supported by SQLCMD.

Here is a block of code to call SQLCMD:

 

string tmpFile = Path.GetTempFileName();

string argument = string.Format(@" -S {0} -d {1} -i ""{2}"" -o ""{3}""",
    ServerName, DatabaseName, fileName, tmpFile);

// append user/password if not use integrated security
if (!connection.IsIntegratedSecurity)
    argument += string.Format(" -U {0} -P {1}", User, Password);

var process = Process.Start("sqlcmd.exe", argument);
process.StartInfo.UseShellExecute = false;
process.StartInfo.CreateNoWindow = true;
process.Start();
while (true)
{
    // wait for the process exits. The WaitForExit() method doesn't work
    if (process.HasExited)
        break;
    Thread.Sleep(500);
}

Performance tuning tips for ASP.NET and IIS 7

1. Browser caching

In part 1, we looked at how it was possible to set an expiration header to any static file such as JavaScript and CSS files, so the browser would cache them for a long time and thereby optimize both for bandwidth and the number of requested files going from server to browser.

The problem with setting a browser cache expiration date of i.e. a JavaScript file to a year in the future becomes clear when you change the file before it expires in your visitor’s browsers. They simply won’t see the changes until they either clear their cache or hits F5 manually.

2. Bundle multiple files

Another common website performance issue is that there are many JavaScript and CSS files included on a page. This scenario results in the browser have to download a lot of extra files and that all slows down the performance of a website. The solution to this is also very simple when you’ve first completed the above steps to register the HTTP handler in web.config and called the BundleHelper.InsertFile method when inserting JavaScript and CSS files.

3. HTTP compression

You’ve always been able to perform HTTP compression in ASP.NET by using third-party libraries or own custom built ones. With IIS 7 you can now throw that away and utilize the build-in compression available from the web.config. Add the following line to enable HTTP compression:

<urlCompression doDynamicCompression=”true” doStaticCompression=”true” dynamicCompressionBeforeCache=”true”/>

By default, only text based content types are compressed.

4. Cache static files

To speed up the load time for the visitors, it is crucial that everything that can be cached by the browser IS cached by the browser. That includes static files such as images, stylesheets and script files. By letting the browser cache all these files means it doesn’t need to request them again for the duration of the cache period. That saves you and your visitors a lot of bandwidth and makes the page load faster. A well primed browser cache also triggers the load and DOMContentLoaded event sooner.

It’s worth noticing that the output caching respects file changes and therefore refreshes ever time changes are made to the JavaScript and CSS files tunnelled through this code.

Optional Parameters in C# 4.0

Some members of the C# community were discussing optional parameters and the implications for future versions when optional parameter values change.  In short, you need to realize that changing the value of optional parameters in a public API is a change that is observable at client code. The ramifications vary greatly, from “no big” to “stop the world”. I’ll give a brief explanation of how the feature works, and what you need to watch for and how to separate reasonable caution from irrational fear from using a feature.

While most modern programming languages provide some way of declaring optional function parameters, C# doesn’t provide a way of directly doing so, despite the fact that VB.NET and .NET’s attribute system both support this functionality. This is a subject of some debate currently in the C# community. The C# development team’s position seems to boil down to the following: When provided, this feature is usually nothing more than dressing up method overloading with a little syntactic sugar.

When you get right down to it, their position makes some sense. A function with an optional parameter is in reality two different functions: one that assumes some default behavior if the optional parameter is omitted, and another that performs more specific behavior based on the value of the optional parameter if provided. But that doesn’t change the fact that using overloaded methods to provide optional parameter support feels a little clunky. It works, but you always wind up writing more code, and you pollute your object interface with the extra method signatures required to support all of your optional parameters. Let’s look at some alternatives.

Difference betweenTryParse and Convert in C#

TryParse

int index;
int.TryParse(Request.QueryString["index"], out index);

This version isn’t so bad since it requires no conditional processing. The problem with the TryParse method is the out parameter, which requires the initial declaration of variable whether or not you want or need it. This also prevents it from being used in a declarative statement, since the return value is whether the value was parsed. This can be used declaratively using the ternary operator, but it is rather odd since the result is already defined. Many people opt to use imperative logic instead, testing for !<t>.TryParse.

Here’s are examples of non-zero default value. The first using an if statement and the second with the ternary operator.

int index;
if (!int.TryParse(Request.QueryString["index"], out index))
{
    index = 1;
}
int index;
index = int.TryParse(Request.QueryString["index"], outindex) ? index : 1;

Convert

var index = Convert.ToInt32(Request.QueryString["index"]);

Convert is more declarative in this form, but it has a fatal flaw. If the string being parsed is an invalid value (not null, but something like “asdf”), then it will throw an exception. Exceptions are expensive, and it requires wrapping the code in a try… catch block since the exception is typically meaningless aside from preventing the assignment. Perhaps the above statement would be better expressed as:

int index = 0;
try
{
    index = Convert.ToInt32(Request.QueryString["index"]);
}
catch { }

The typical conversion failure use case is to assign a default value. However, additional logic is sometimes necessary. With TryParse, you test the return value for false. With Convert, you catch the exception. With Maybe, you test for null.

int? result = Maybe.ToInt32(Request.QueryString["index"]); if (result == null) { // Failure processing }

Since it is sometimes necessary to know if a the parsing was successful, I didn’t opt to create a ParseWithDefault method.


Visual Studio 2010 Pro Power Tools, It Is Free!

A set of extensions to Visual Studio Professional (and above) which improves developer productivity.

  • Searchable Add Reference Dialog
    The new Add Reference dialog makes it faster and easier for you to find the reference that you are looking for and add it to your VB, C# or F# project.  From the Solution Explorer, simply right click on the References node, select the Add Reference command to see the updated Add Reference Dialog. 
  • Highlight Current Line
    As the resolution of monitors increases, it’s becoming more difficult to find the caret in the code editor.  The highlight current line extension makes it easy to find the caret by highlighting the line that the caret is on in the editor.  You can even configure the default colour by changing the setting for “Current Line (Extension)” and “Current Line Inactive (Extension)” in Tools Options Fonts & Colors. 
  • HTML Copy
    This extension provides support for the HTML Clipboard format when copying code from the editor.  This means that you’ll no longer have to go fix up the formatting of your code when you paste it into a TFS bug form or any other HTML based control. 
  • Triple Click
    It’s never been easier to select a line of code from the mouse by simple triple-clicking anywhere on the line. 
  • Fix Mixed Tabs
    Some developers prefer tabs, others prefer spaces, and nobody likes mixing tabs & spaces.  This extension promotes developer harmony by warning as they are open or save a file that has a mixture of tabs & spaces.  The information bar also provides an easy way to fix the file to suit your preference. 
  • Ctrl + Click Go To Definition
    This extension gives the editor a web browser by adding clickable hyperlinks to symbols in your code as you hold down the Ctrl key.
  • Colorized Parameter Help
    This extension improves consistency with the editor by applying syntax highlighting to the contents of the Parameter Help window for C# &VB. 
  • Move Line Up/Down Commands
    This extension maps the Alt+Up Arrow & Alt+Down Arrow keys such that they will move the current line of code or the selected lines up and down through the editor. 
  • Column Guides
    Since Visual Studio 2002, there has been a not so secret registry key which allowed user to draw a vertical line in the code editor.  This is very useful to remind developers that their full line of code or comments may not fit one a single screen. Thanks to this extension this feature has returned with UI configure it.  Simply place the cursor at the appropriate column and select Add Guideline from the context menu

Building the Http Module with Logging Application Block

Building the Http Module

In order to build an Http module we only need to implement
the IHttpModule interface. The following is a simple
LoggingHttpModule which log details when a web request start
and when web request end:

using System;
using System.Web;
using Microsoft.Practices.EnterpriseLibrary.Common.Configuration;
using Microsoft.Practices.EnterpriseLibrary.Logging;
 
namespace HttpModules
{
  public class LoggingHttpModule : IHttpModule
  {
    #region Members
 
    private LogWriter _writer;
 
    #endregion
 
    #region IHttpModule Members
 
    public void Dispose()
    {
      if (_writer != null)
      {
        _writer.Dispose();
      }
    }
 
    public void Init(HttpApplication context)
    {
      CreateLogWriter();
      context.BeginRequest += new EventHandler(context_BeginRequest);
      context.EndRequest += new EventHandler(context_EndRequest);
    }
 
    private void CreateLogWriter()
    {
      ConfigureEnterpriseLibraryContainer();
      _writer = EnterpriseLibraryContainer.Current.GetInstance<LogWriter>();
    }
 
    private void ConfigureEnterpriseLibraryContainer()
    {
      var builder = new ConfigurationSourceBuilder();
 
      builder.ConfigureInstrumentation().EnableLogging();
      builder.ConfigureLogging().WithOptions
             .LogToCategoryNamed("General")
               .WithOptions
               .SetAsDefaultCategory()
               .SendTo
               .FlatFile("Log File")
               .FormatWith(new FormatterBuilder()
               .TextFormatterNamed("Textformatter"))
                   .ToFile("file.log");
 
      var configSource = new DictionaryConfigurationSource();
      builder.UpdateConfigurationWithReplace(configSource);
      EnterpriseLibraryContainer.Current =
        EnterpriseLibraryContainer.CreateDefaultContainer(configSource);
    }
 
    void context_BeginRequest(object sender, EventArgs e)
    {
      _writer.Write(new LogEntry
      {
        Message = "BeginRequest"
      });
    }
 
    void context_EndRequest(object sender, EventArgs e)
    {
      _writer.Write(new LogEntry
      {
        Message = "EndRequest"
      });
    }
 
    #endregion
  }
}

Using The Module

In order to use the module all we need to do is to add a reference
to the class library that holds the LoggingHttpModule. Then we need
to register the module in the web.config file in the httpModules 
element like:

<httpModules>
    <add name="LoggingHttpModlue" type="HttpModules.LoggingHttpModule, HttpModules"/>
</httpModules>

That is it. Now the module will be executed whenever a request
start or end.