About the author

Miron Abramson
Me
Software Engineer,
CTO at PixeliT
and .NET addicted for long time.
Open source projects:
MbCompression - Compression library

Recent comments

Authors

Disclaimer

The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.

© Copyright 2014

Creative Commons License

Blog Flux Directory
Technology Blogs - Blog Top Sites

Caution When passing Null or DateTime into Store Procedure

Every small to big web application is using DataBase, and I don't neet to explain the importance of using Store Procedures. If we use directly the SqlCommand, or using any DAL component, we need to take care when trying to send null or DateTime to the Store Procedure: SQL-Server null value is not the same as null in .NET.  Null in .NET means that a reference variable does not reference an object instanc. That is, a reference variable can reference an object instance OR be "null", not both. DBNull.Value is a reference to an object instance of type DBNull. Therefore DBNull.Value is not "null". But, when we are sending null to the Store Procedure we actualy mean that we want the value of the parameter to be empty and to be 'null' in the DataBase. If we set a SqlParameter value to 'null', we will get an Exception, so we need to convert it  to DBNull.Value before sending it to the Store Procedure.

Another thing we need to be aware of, that the minimum and the maximum value of DateTime in .NET and in SQL-Server are not the same. .NET DateTime minimum value is 1/1/0001 00:00:00 and the maximum is 12/31/9999 23:59:59.999, while Sql minimum value is 1/1/1753 00:00:00.003 and the maximum is  12/31/9999 23:59:59.997 If we will try to send to the SP a datetime that is less then the minimum of the Sql or DateTime.MaxValue, we will get an Exception, so we need to  currect it before.

Here is a simple method to cover both  cases - null & DateTime:

private static void DoSafeParameter(ref SqlParameter dbParameter)
{
    if (dbParameter.Direction == ParameterDirection.Input || dbParameter.Direction == ParameterDirection.InputOutput)
    {
        if (dbParameter.Value == null)
        {
            dbParameter.Value = DBNull.Value;
        }
        else if (dbParameter.SqlDbType == SqlDbType.DateTime)
        {
            if (((DateTime)dbParameter.Value) < System.Data.SqlTypes.SqlDateTime.MinValue.Value)
            {
                dbParameter.Value = System.Data.SqlTypes.SqlDateTime.MinValue.Value;
            }
            else if (((DateTime)dbParameter.Value) > System.Data.SqlTypes.SqlDateTime.MaxValue.Value)
            {
                dbParameter.Value = System.Data.SqlTypes.SqlDateTime.MaxValue.Value;
            }
        }

    }
}

(I choosed to convert any DateTime that is less then the Sql value to SqlDateTime.MinValue in any cases)

Note

All this is not relevant when using Enterprise Library. It do this for you.

Currently rated 5.0 by 3 people

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Posted by Miron on Wednesday, September 26, 2007 7:22 PM
Permalink | Comments (4) | Post RSSRSS comment feed

Compress your pages, css, js and WebResources.axd files for better performance

(See updated post:  New & Shiny WebResource.axd compression Module

This post is an update for my previews post about http compression. In that post, I posted a http module that compress aspx pages and WebResource.axd files.
Thanks to Mads Kristensen, that found a performance issue in my code and had a solution for that, I improved my compressor component and also I included a complete project to compress asp.net pages, CSS files, JavaScript files and WebResource.axd files as well. The implementation in really very simple and not lot of changes are necessary in existing project. The page compression is very simple, and common to all http compressors:
 Registering the httpmodule in the web.config:

<add name="HttpCompressionModule" type="Miron.HttpHandlersAndModules.HttpCompressionModule"/>

and the compression itself in the httpmodule: 

HttpApplication app = sender as HttpApplication; 

// Check if GZIP is supported by the client

if (IsGzipEncodingSupported())
{
    app.Response.Filter = new GZipStream(app.Response.Filter, CompressionMode.Compress);

    SetEncodingType(GZIP);   // Set the response encoding type header
}
// Check if DEFLATE is supported by the client
else if (IsDeflateEncodingSupported())
{
    app.Response.Filter = new DeflateStream(app.Response.Filter, CompressionMode.Compress);

    SetEncodingType(DEFLATE);  // Set the response encoding type header
}

The WebResource.axd compression is a bit more complicate, but the idea is to make a 'fake' request based on the requested url when the client asked for WebResource.axd file, get the response into byte[], compress it into MemoryStream cache it as a byte[] and send it to the client. The next time the client ask for this WebResource, it served from the cache (thanks again to Mads Kirstensen). The compression is only when the WebResource serve css or javascript files. over wise, the WebResource is send to the client 'as it'.   The CSS and the JS files compression is similar to the page compression, the differents  are that in those cases, we load the requested file, read it into string, manipulate it  (remove unneeded spaces and stuff), compress it, cache it, and send it to the client. The 'problem' is that css and js files are served by the IIS itself, and not by ASP.NET engine, so what we do is, changing the 'src' attribute for js files to jslib.axd or the 'href' attribute for css files to css.axd, and add as query string the real files name (see in the ReadMe.txt file how it done), and those files are handled by ASP.NET engine and to compress tham - for that, we register the following handlers in the web.config: (another option, is to serve those files via WebResources)

<add verb="*" path="jslib.axd" type="Miron.HttpHandlersAndModules.JavaScriptHandler" validate="false"/>

<add verb="*" path="css.axd" type="Miron.HttpHandlersAndModules.CssCompressionHandler" validate="false"/>

The caching for those files have CacheDependency on the files, so the content is removed from the cache in the moment the files are changed, and reload again when requested. Before sending data to the client, we check the ETag, and if its the same as the client sent, so we can stop the response and send only the code 304. 

Extra features

By configuration in the web.config, it is possible to disable any compression type, decide the time (by days) the cached file will be in the cache, and also it is possible to specified mimeTypes content to not compress or specified aspx files to exclude from the compression.  All configuration description in the ReadMe.txt file. 

 Implementation 

All implementation instructions are in the attach zip file in ReadMe.txt file.

Note

The WebResource compression may not work if the request is url that modified in the windows 'host' file. In that case, you will need to disable WebResource compression (See in the  ReadMe.txt)

  (See update post with new & better code: New & Shiny WebResource.axd compression Module)

Latest code can be downloaded from:

http://www.codeplex.com/MbCompression

Currently rated 3.9 by 14 people

  • Currently 3.928571/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Posted by Miron on Monday, September 24, 2007 8:17 AM
Permalink | Comments (17) | Post RSSRSS comment feed

Grab all email addresses from string, file or site

While I was working on a "Social network" project, I had to give the user interface to 'Invite friends' - as in every social network application. So, I add a page with 10 TextBoxes, add a RegularExpression validator to each one, let the user fill them, and send email to each email he filled. The users complained that it is not comfortable couse most of them were copy their friend's emails from their gmail account, and gmail uses a big TextBox with all the emails and names mixed. So the solution to do the same functionality is quite simple.  Using RegularExpression we can get a MatchCollection of all strings that match our regular expression pattern. I used the following regular expression, but you can use anything. (I'm open for suggestions) :

 private const string strRegex = @"\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}\b";

using System.Text.RegularExpressions; 

public System.Collections.Specialized.StringCollection CollectFromString(string input)
{
    System.Collections.Specialized.StringCollection sc = new System.Collections.Specialized.StringCollection();
    if (string.IsNullOrEmpty(input)) return sc;
    MatchCollection mc = Regex.Matches(input, strRegex, RegexOptions.IgnoreCase);
    for (int i = 0; i < mc.Count; i++)
    {
        if (!sc.Contains(mc[i].Value))
        {
            sc.Add(mc[i].Value);
        }
    }
    return sc;
}

With this method you can just "drop" a big multi-line TextBox, and let the user enter his emails with any format he want - emails sperates with ',' or ';' or with ever char that is not valid as en email, and even mix the emails with names by copy & paste from his favorite email client.  The same functionality but collecting from file is quite the same:

public System.Collections.Specialized.StringCollection CollectFromFile(string fileName)
{
    System.Collections.Specialized.StringCollection sc = new System.Collections.Specialized.StringCollection();
    if (string.IsNullOrEmpty(fileName)) return sc;
    if (!System.IO.File.Exists(fileName))
        throw new System.IO.FileNotFoundException();
    using (System.IO.StreamReader sr = new System.IO.StreamReader(fileName))
    {
        string str = sr.ReadToEnd();
        sr.Close();
        return CollectFromString(str);
    }
}

And the last method  is to collect all emails from a given web site (one page):

public System.Collections.Specialized.StringCollection CollectFromSite(string url)
{
    System.Collections.Specialized.StringCollection sc = new System.Collections.Specialized.StringCollection();
    if (string.IsNullOrEmpty(url)) return sc;

    System.IO.Stream st = null;

    if (!url.StartsWith("http://"))
        url = "http://" + url;

    try
    {
        // make a Web request
        System.Net.WebRequest req = System.Net.WebRequest.Create(url);
        // get the response and read from the result stream
        System.Net.WebResponse resp = req.GetResponse();
        st = resp.GetResponseStream();
        using (System.IO.StreamReader sr = new System.IO.StreamReader(st))
        {
            return CollectFromString(sr.ReadToEnd());
        }
    }
    finally
    {
        if (st != null)
            st.Dispose();
    }
}

 

In the source code bellow, I  added some more functionalities and wrapped all in a collection to be "generic" and it can be use easly in other projects. 

CustomCollections.rar (4.10 kb)

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Categories: ASP.NET | C#
Posted by Miron on Thursday, September 13, 2007 1:23 AM
Permalink | Comments (1) | Post RSSRSS comment feed

Compress pages and WebResource.axd files in ASP.NET

(See updated post: Compress your pages, css, js and WebResources.axd files for better performance)

I will not be long with words, becouse lot of good articles about http compression are all around the internet. ASP.NET gives us the great ability to filter the data that passing between the server and the client. One of the powerfull uses of that ability is to compress that data. Almost all of the latest versions of the browsers support http compression "built-in" in their side (the client side), So, that is there to be used ! I build my http module to be as simple as posible, and added comments that it will be understandable to most of the readers. The module will check the compression type that the client support (if at all) and use that type to compress the results of the page response, or the WebResourse.axd content that need to be sent to the client. Also, you can configure (using the web.config file - See ReadMe.txt file)  to specified mime types that generated by the page to be exclude and not be compressed, or specified specific pages to also be exclude from the compression.  I added support for MS-AJAX by disable the compression for ajax post-backs, but I never tested it with another AJAX framework, so any comments about that will be  happily receive.  Fill free to use this module on your own risk, and without any guarantee or warranty. Note that JavaScript files or CSS files with their normally form will not be compressed by this module, but WebResource.axd that contains that types will be compressed. Any comments will be happily receive ! 

P.B.

Compressing WebResource.axd files will increae your score in YSlow performance check  ;-)

Full Source code: 

See update source in the post:

New & Shiny WebResource.axd compression Module

Currently rated 4.7 by 6 people

  • Currently 4.666667/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Categories: ASP.NET | C#
Posted by Miron on Friday, September 07, 2007 10:38 AM
Permalink | Comments (3) | Post RSSRSS comment feed

Choosing my .NET blog engine

Long time that I want start my own blog, but I never had the time for that. Few days ago, I decided - that's it - Today is the day.

I was playing around, download source of some Open Source ASP.NET blogs as dasBlogsubText,  and BlogEngine.NET and look at their code. All of them are written in high level code, All of them - for sure are doing their job perfect.

But the one that cached my eyes first was BlogEngine.NET. The code is very simple, very clean - exectly as Mads Kristensen wrote in his blog: "KISS – Keep It Simple, Stupid. I quickly played with the code, add some of my own tweaks, create my own theme, upload the blog to my hosting account at GoDaddy (must not forget to remove the trust level from the Web.Config)  and as you can see - the blog is up and running!

To BlogEngine.NET team - Keep going with your great work!

Currently rated 5.0 by 4 people

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Posted by Miron on Monday, September 03, 2007 9:17 PM
Permalink | Comments (6) | Post RSSRSS comment feed

Check all CheckBoxes in GridView in client side

'Lists' controls as GridView, DataList or Repeater sometimes have a column with CheckBoxes. It is very usefull to let the user 'Select all' or 'Un Select all'. One way to do it is to loop on the control in the code behind and check/un check the CheckBoxes, or faster way is to do it on the client side, using the same idea of my preview  post:

//
//  Select or unSelect checkboxes in grid view
//
function CheckAllCheckBoxes(aspxCheckBoxID, checkVal)
{
    var reg = new RegExp( aspxCheckBoxID + "$" );
    var pageElements = document.getElementsByTagName("*");
    for(i = 0; i < pageElements.length; i++) {
        elm = pageElements[i];
        if (elm.type == 'checkbox')
        {
            if (reg.test(elm.name))
            {  
                elm.checked = checkVal
            }
        }
    }
 }

Where 'aspxCheckBoxID' is the CheckBox server side name, and 'checkVal is value if to check all or uncheck all. So simple.

Happy coding 

Currently rated 4.8 by 5 people

  • Currently 4.8/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Categories: ASP.NET | Client side
Posted by Miron on Saturday, September 01, 2007 5:55 PM
Permalink | Comments (1) | Post RSSRSS comment feed