:::: MENU ::::

Tuesday, June 2, 2009

In this post I will explain you how authenticate the request directly coming to access a file that is downloadable. some thing like *.pdf or *.zip.

Mostly, people make it working by creating an *.aspx page and then write binary of that file in Response.WriteFile. So, user will have no idea where the file is coming from. now this is the fair approach but what if somebody, somehow know the path of downloadable files.

So, to stop the un authenticated access to our files, we will first create a session enable HTTP handler.

public class MyHttpHandler : IHttpHandler, IReadOnlySessionState

{

 

    public void ProcessRequest(HttpContext context)

    {

        if (context.Session["userId"] == null)

        // I am using a session variable you can also use context.User.Identity.IsAuthenticated

        {

            context.Response.Redirect("/login.aspx?retUrl=" + context.Request.RawUrl);

            //Redirecting to the login page ... alternatively you can also set context.Response.StatusCode

        }

    }

 

    public bool IsReusable

    {

 

        get { return false; }

    }

}

Now, once we have created that. Let me register my newly creater handler for *.zip and *.pdf files in web.config.

 

<httpHandlers>

  <add verb="*" path="*.zip" type="LearningApp.MyHttpHandler, LearningApp"/>

  <add verb="*" path="*.pdf" type="LearningApp.MyHttpHandler, LearningApp"/>

</httpHandlers>

That’s it. If you want more file types to be authenticated add more verbs in handler section of HttpHandler.

Don’t try to put *.* : That can create some serious problem because then each of your *.aspx, *asmx and all your logic stuff will need authentication.

 

Today is the day that I'm finally able to speak about why things have been pretty quiet lately regarding the future of GhostDoc.

I'm happy to announce GhostDoc has been acquired by SubMain, developer of tools like CodeIt.Right. The agreement covers the usage of GhostDoc's documentation generation technology in their products, as well as the availability of GhostDoc as a standalone product. SubMain will continue to maintain and distribute a non-crippled version of GhostDoc free of charge, and will make sure that it will work with future versions of Visual Studio like the upcoming VS2010. The first step is a new version 2.5 of GhostDoc that has been released just moments ago.

For more information please take a look at a Q&A with Serge Baranovsky from SubMain and me that covers past, present and future of GhostDoc.

As I already mentioned in the Q&A, from my experiences of working with the guys at SubMain (both on the legal and the technical stuff), I can say that GhostDoc is in good hands. The developers now have my issue tracking database where I collected and annotated all the feature requests of the recent years, but I also would like to ask every GhostDoc user to please let them know if you have ideas how to improve this tool.

I'd like to use this opportunity to say a big Thank You to all GhostDoc users out their for their (overwhelmingly positive) feedback over the recent years. Thank You!
 

Update: Important note for existing GhostDoc users
There are uninstall issues with the old GhostDoc version 2.1.3 (and versions before) that under specific circumstances may lead to losing your Visual Studio settings on Vista machines. I'm already working on a solution to the problem (with help from one of the SubMain developers), in the meantime please back up your settings as described in this step-by-step guide before uninstalling the old GhostDoc version. During uninstallation, if a Visual Studio instance pops up and asks you to choose a developer profile, choose one and continue. This will lead to the loss of the settings, which then can be restored by importing the backup you just made before. Note that you have to choose a profile; cancelling the dialog will lead to a corrupted state of the uninstallation.

The new GhostDoc from SubMain is using different install/uninstall/VS integration technology that has been proven in their other products and does not have such problems.

More

Monday, June 1, 2009

I have absolutely no hesitation in stating that jQuery is the most popular JavaScript and AJAX framework available. Now-a-days, developers caught by this wave, tend to ease their client-side development by using jQuery wherever and whenever they can. I came across a similar requirement when one of my clients requested me a POC (Proof of Concept) of using jQuery with the ASP.NET CustomValidator validation control. This article discusses how to validate an Address field using the ASP.NET CustomValidator and jQuery.

I assume you are familiar with jQuery. If you are new to jQuery, then before moving ahead, I would recommend you to check out Using jQuery with ASP.NET - A Beginner's Guide. Please do take a note that this example uses the latest version of jQuery 1.3.2 and jQuery 1.3.2 Visual Studio 2008 Autocomplete documentation.

 

A Brief note about the CustomValidator control

 

The CustomValidator control performs a field’s validation based on custom validation logic that you provide. Using this control, you can write server-side validation code using C# or VB.NET as well client-side validation code using JavaScript, to check user input.

Note: Always remember to perform server-side validation.

Since the focus of this article is to integrate jQuery and the ASP.NET CustomValidator control, I will jump straight to the basics of ClientSide Validation with the CustomValidator control. When we do client-side validation, the JavaScript function to be used looks similar to the following:

function ClientSideValidation(source, args)

where ‘source’ is a reference to the validation control and ‘args’ is the object whose ‘Value’ property represents the data to be validated. The args.IsValid property determines if the data validates (true) or does not validate (false).

The ‘ClientFunctionName’ property of the CustomValidator control associates your client-side code with the CustomValidator.

Typically, this is how you would do Client-Side Validation using JavaScript

 

    <asp:Textbox id="TextBox1" runat="server" text=""></asp:Textbox>

    <asp:CustomValidator id="custV" runat="server"

      ControlToValidate = "TextBox1"

      ErrorMessage = "Minimum 4 characters required"

      ClientValidationFunction="CheckLength" >

    </asp:CustomValidator>

...

<script type="text/javascript">

     function CheckLength(sender, args) {

         args.IsValid = (args.Value.length >= 4);

     }

</script> 

   

</head>

Let us see how to do the same using jQuery.

Assuming you have downloaded the jQuery files stated in the beginning of this article, create a reference to the jQuery 1.3.2 file in the <head> section of your page as shown below:

 

<head runat="server">

    <title>CustomValidator using jQuery</title>

 

    <script src="Scripts/jquery-1.3.2.js" type="text/javascript"></script>

   

Now drag and drop a TextBox, a Button control and the CustomValidator control to the page. Set the TextMode=”Multiline” property of the TextBox to convert it to a <textarea>. The TextBox will be used by users to enter ‘Address’ information. The requirement is that the minimum characters to be entered in the TextBox should be 10, Maximum characters should not exceed 50 and that the TextBox allows only AlphaNumeric characters along with a few special characters like &().

Disclaimer: A CustomValidator control is used when the other ASP.NET validation controls does not suit your needs. However the ‘Address’ field requirement described above, is possible to achieve using the RegularExpression Validator control. Having said that, the focus of this article is to just demonstrate how to use jQuery with the CustomValidator control, and to be honest, I felt this example is a good candidate to demonstrate the code brevity achieved using jQuery, while validating the Address field. Moving ahead…

After setting up a few properties on the CustomValidator control, the markup will look similar to the following:

 

    <asp:Label ID="Label1" runat="server" Text="Address : "></asp:Label>

    <asp:TextBox ID="TextBox1" TextMode="MultiLine" runat="server" CssClass='txtAdd'/>

    <br />

        <asp:CustomValidator ID="CustomValidator1" runat="server" Display="Dynamic"

        ErrorMessage="Field cannot be blank<br/>Minimum 10, Maximum 50 chars allowed<br/>Only AlphaNumeric and Special Characters like &()- allowed"

        ClientValidationFunction="chkAddressField"

            onservervalidate="CustomValidator1_ServerValidate" >

        </asp:CustomValidator>

    <br />

    <asp:Button ID="Button1" runat="server" Text="Submit" />

   </div>  

C#

    protected void CustomValidator1_ServerValidate(object source, ServerValidateEventArgs args)

    {

        // Write your Server side validation code here.

    }

VB.NET

      Protected Sub CustomValidator1_ServerValidate(ByVal source As Object, ByVal args As ServerValidateEventArgs)

            ' Write your Server side validation code here.

      End Sub

 

Observe that the ClientValidationFunction is pointing to the chkAddressField() method. This is the client-side Method that will check user input before the page is submitted. The server-side method has been created but kept empty since that is not the focus of this article.

It’s time to introduce jQuery now. Write the following code in the <head> section of your page

<head runat="server">

    <title>CustomValidator using jQuery</title>

 

    <script src="Scripts/jquery-1.3.2.js" type="text/javascript"></script>

   

    <script type="text/javascript">

        function chkAddressField(sender, args) {

            args.IsValid = false;

            $(".txtAdd").each(function() {

                if (/^[A-Za-z0-9&()-]{10,50}$/.test(this.value)) {

                    args.IsValid = true;

                }              

            });           

        }

    </script>

</head>

 

In the code above, to start with, we are setting the args.IsValid property to ‘false’. The property is set to ‘true’ only if the text entered in the textbox (with class ‘txtAdd’) passes the regex validation.

If the user enters characters less than 10 or greater than 50 or a character that’s not allowed, then the validation occurs at client side and prevents the user from submitting the form as shown below

 

Friday, May 22, 2009

I’ve had several people ask me lately about encrypting data in .NET.  I’m not sure why the question has come up a lot recently, but it’s definitely something good to know if you have any sensitive data that needs to be stored.  .NET provides two main encryption roads that you can travel down including symmetric encryption and asymmetric encryption.  Symmetric encryption relies upon a private key to encrypt and decrypt while asymmetric encryption relies upon a public key to encrypt and a private key to decrypt.  Symmetric encryption provides the best performance while asymmetric encryption provides the best security in situations where keys need to be exchanged between different parties.  If you need to encrypt and decrypt data directly within an application symmetric encryption works fine as long as other prying eyes can’t get their hands on the private key (or your source code). 

I have a fairly straightforward encryption/decryption class named Encryptor that I use when I need to perform symmetric encryption in my web applications.  The class relies upon a symmetric algorithm called Rijndael that can be used to encrypt and decrypt data. 

While I’m not going to provide a detailed discussion of what the class does I’m happy to post it here for anyone who needs that type of functionality.  Keep in mind that you’ll need to update the password and salt values to whatever you need to use in your applications and should consider dynamically grabbing the password from a secured data store as opposed to hard-coding it in the source code (especially if you’ll be shipping the assembly…people can disassemble it using tools like Reflector).  The salt acts as a type of junk data that is used in constructing the password and can also be used to pad encrypted data with bogus bytes so that hackers don’t know which part of the data is valid and which part is junk.

using System;

using System.IO;

using System.Security.Cryptography;

 

namespace YourApp.Model.Helpers {

   

    internal class Encryptor

    {

        internal static string Decrypt(string cipherText)

        {

            byte[] cipherBytes = Convert.FromBase64String(cipherText);

            Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(_Pwd, _Salt);

            byte[] decryptedData = Decrypt(cipherBytes, pdb.GetBytes(32), pdb.GetBytes(16));

            return System.Text.Encoding.Unicode.GetString(decryptedData);

        }

 

        private static byte[] Decrypt(byte[] cipherData, byte[] Key, byte[] IV) {

            MemoryStream ms = new MemoryStream();

            CryptoStream cs = null;

            try {

                Rijndael alg = Rijndael.Create();

                alg.Key = Key;

                alg.IV = IV;

                cs = new CryptoStream(ms, alg.CreateDecryptor(), CryptoStreamMode.Write);

                cs.Write(cipherData, 0, cipherData.Length);

                cs.FlushFinalBlock();

                return ms.ToArray();

            }

            catch {

                return null;

            }

            finally {

                cs.Close();

            }

        }

 

        public static string Encrypt(string clearText)

        {

            byte[] clearBytes = System.Text.Encoding.Unicode.GetBytes(clearText);

            Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(_Pwd, _Salt);

            byte[] encryptedData = Encrypt(clearBytes, pdb.GetBytes(32), pdb.GetBytes(16));

            return Convert.ToBase64String(encryptedData);

        }

 

 

        private static byte[] Encrypt(byte[] clearData, byte[] Key, byte[] IV)

        {

            MemoryStream ms = new MemoryStream();

            CryptoStream cs = null;

            try

            {

                Rijndael alg = Rijndael.Create();

                alg.Key = Key;

                alg.IV = IV;

                cs = new CryptoStream(ms, alg.CreateEncryptor(), CryptoStreamMode.Write);

                cs.Write(clearData, 0, clearData.Length);

                cs.FlushFinalBlock();

                return ms.ToArray();

            }

            catch

            {

                return null;

            }

            finally

            {

                cs.Close();

            }

        }

 

        static string _Pwd = "Your_Password_Goes_Here"; //Be careful storing this in code unless it’s secured and not distributed

        static byte[] _Salt = new byte[] {0x45, 0xF1, 0x61, 0x6e, 0x20, 0x00,  0x65, 0x64, 0x76, 0x65, 0x64, 0x03, 0x76};

    }

}

 

To use the class to encrypt data (and get back a Base64 encoded string) the following code can be written:

string creditCardNumber = Encryptor.Encrypt(cust.CreditCardNumber);

 

Wednesday, May 20, 2009

.Net Framework 4.0 provides us with a new class called Lazy<T>. As documentation sais then Lazy<T> provides support for several common patterns of lazy initialization, including the ability to initialize value types and to use null values. So it is construct that helps us implement lazy loading.

I wrote a little code example on Visual Studio 2010 that illustrates how to use Lazy<T>.


static void Main(string[] args)
{
    var lazyString = new Lazy<string>(
        () =>
        {
            // Here you can do some complex processing
            // and then return a value.
    
Console.Write("Inside lazy loader");
            return "Lazy loading!";
        });
    Console.Write("Is value created: ");
    Console.WriteLine(lazyString.IsValueCreated);
 
    Console.Write("Value: ");
    Console.WriteLine(lazyString.Value);

   
Console.Write("Value again: ");
    Console.WriteLine(lazyString.Value);

   
Console.Write("Is value created: ");
    Console.WriteLine(lazyString.IsValueCreated);
 
    Console.WriteLine("Press any key to continue ...");
    Console.ReadLine();
}

When we run this code we will get the following output.

    Is value created: False
    Inside lazy loader
    Value: Lazy loading!
    Value again: Lazy loading!
    Is value created: True
    Press any key to continue …

The value of our Lazy<string> will be initialized when we first ask it and then it will be stored for subsequent calls. Notice that there is one Console.WriteLine inside lazy initialization function and if you look at output you can see that this function is run only once. So only thing you have to do is to write initialization function and Lazy<T> makes all the work automatically.

I found also one example that may give you better explanations about internals of Lazy<T>: Lazy Computation in C#.

 

Tuesday, May 19, 2009

Unit Testing ASP.NET? ASP.NET unit testing has never been this easy.

Typemock is launching a new product for ASP.NET developers – the ASP.NET Bundle - and for the launch will be giving out FREE licenses to bloggers and their readers.

The ASP.NET Bundle is the ultimate ASP.NET unit testing solution, and offers both Typemock Isolator, a unit test tool and Ivonna, the Isolator add-on for ASP.NET unit testing, for a bargain price.

Typemock Isolator is a leading .NET unit testing tool (C# and VB.NET) for many ‘hard to test’ technologies such as SharePoint, ASP.NET, MVC, WCF, WPF, Silverlight and more. Note that for unit testing Silverlight there is an open source Isolator add-on called SilverUnit.

The first 60 bloggers who will blog this text in their blog and tell us about it, will get a Free Isolator ASP.NET Bundle license (Typemock Isolator + Ivonna). If you post this in an ASP.NET dedicated blog, you'll get a license automatically (even if more than 60 submit) during the first week of this announcement.

Also 8 bloggers will get an additional 2 licenses (each) to give away to their readers / friends.

Go ahead, click the following link for more information on how to get your free license.

Unit Testing ASP.NET? ASP.NET unit testing has never been this easy.

Typemock is launching a new product for ASP.NET developers – the ASP.NET Bundle - and for the launch will be giving out FREE licenses to bloggers and their readers.

The ASP.NET Bundle is the ultimate ASP.NET unit testing solution, and offers both Typemock Isolator, a unit test tool and Ivonna, the Isolator add-on for ASP.NET unit testing, for a bargain price.

Typemock Isolator is a leading .NET unit testing tool (C# and VB.NET) for many ‘hard to test’ technologies such as SharePoint, ASP.NET, MVC, WCF, WPF, Silverlight and more. Note that for unit testing Silverlight there is an open source Isolator add-on called SilverUnit.

The first 60 bloggers who will blog this text in their blog and tell us about it, will get a Free Isolator ASP.NET Bundle license (Typemock Isolator + Ivonna). If you post this in an ASP.NET dedicated blog, you'll get a license automatically (even if more than 60 submit) during the first week of this announcement.

Also 8 bloggers will get an additional 2 licenses (each) to give away to their readers / friends.

Go ahead, click the following link for more information on how to get your free license.

Friday, May 8, 2009

Sometimes you have to load jQuery, but you don’t know if it has already been referenced somewhere else in the website. 

This tends to happen if you have a custom web control, delivered in an assembly, that relies on jQuery.

This code has been ripped out of my application, and may have a typo or three, but it gives you the general idea.

 

var jQueryScriptOutputted = false;

function initJQuery() {

   

    //if the jQuery object isn't available

    if (typeof(jQuery) == 'undefined') {

   

   

        if (! jQueryScriptOutputted) {

            //only output the script once..

            jQueryScriptOutputted = true;

           

            //output the script (load it from google api)

            document.write("<scr" + "ipt type=\"text/javascript\" src=\"http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js\"></scr" + "ipt>");

        }

        setTimeout("initJQuery()", 50);

    } else {

                        

        $(function() { 

            //do anything that needs to be done on document.ready

        });

    }

           

}

initJQuery();

 

Friday, May 1, 2009

I'm editing in a link to Adam Machanic's blog on this. In the comments on this topic here you will see there are imperfections found in my methods. Reading Adam's blog shows this in more detail.
http://sqlblog.com/blogs/adam_machanic/archive/2009/04/26/faster-more-scalable-sqlclr-string-splitting.aspx

Thanks Adam!

I wrote this short CLR split function awhile back based on a few other articles I read when 2005 was released. I decided to play with it today and see if I could put it with the SQL split solutions.

Let's get the basics out of the way on SQL CLR. SQL CLR is only good once it's in memory. The CLR function split basically won over the T-SQL split functions after it was cached. This is a critical variable to consider when thinking CLR vs. T-SQL options on coding. If you are doing heavy manipulation of data and heavy math, CLR will typically help you, but you should be very careful with CLR and memory management. You can run your server resources out and literally stop functionality. I highly recommend reading MrDenny's blog on CLR here. Denny touches on important topics on when to use CLR and why you shouldn't. After that, look into how SQL Server 32bit, 32bit with AWE and 64bit versions handle memory. Each handles memory differently. AWE enalbed instances will probably be the one that will cause you more headaches then the rest. I had severe memory issues a few months ago on a production database server that forced restarts nightly until I fixed the problem. I analyzed the problem and it came to be several factors that caused it and SQL CLR memory was one of those factors. Here is my chance to thank mrdenny and ptheriault again for the assisatnce on that strange problem.

I went out and google'd "fast split function t-sql". Found a few and tested them against the CLR split method. I found a dozen or so split functions that looked good. I still went with a numbers table one after testing them out next to each other. Here is one of the functions I used. If you have a better one, post it in the comments and I can edit the post.

tsqlLine number On/Off | Show/Hide | Select all

  1. ALTER FUNCTION [dbo].[Split] (
  2. @List VARCHAR(7998), --The delimited list
  3. @Del CHAR(1) = ',' --The delimiter
  4. )
  5. RETURNS @T TABLE (Item VARCHAR(7998))
  6. AS
  7. BEGIN
  8. DECLARE @WrappedList VARCHAR(8000), @MaxItems INT
  9. SELECT @WrappedList = @Del + @List + @Del, @MaxItems = LEN(@List)
  10.  
  11. INSERT INTO @T (Item)
  12. SELECT SUBSTRING(@WrappedList, Number + 1, CHARINDEX(@Del, @WrappedList, Number + 1) - Number - 1)
  13. FROM dbo.Numbers n
  14. WHERE n.Number <= LEN(@WrappedList) - 1
  15. AND SUBSTRING(@WrappedList, n.Number, 1) = @Del
  16.  
  17. RETURN
  18. END

Code is hidden, SHOW

Here is my CLR split

csharpLine number On/Off | Show/Hide | Select all

  1. using System;
  2. using System.Data;
  3. using System.Collections;
  4. using System.Data.SqlClient;
  5. using System.Data.SqlTypes;
  6. using Microsoft.SqlServer.Server;
  7.  
  8. public partial class UserDefinedFunctions
  9. {
  10.     [SqlFunction(Name = "CLR_Split",
  11.     FillRowMethodName = "FillRow",
  12.     TableDefinition = "id nvarchar(10)")]
  13.  
  14.     public static IEnumerable SqlArray(SqlString str, SqlChars delimiter)
  15.     {
  16.         if (delimiter.Length == 0)
  17.             return new string[1] { str.Value };
  18.         return str.Value.Split(delimiter[0]);
  19.     }
  20.  
  21.     public static void FillRow(object row, out SqlString str)
  22.     {
  23.         str = new SqlString((string)row);
  24.     }
  25. };

Code is hidden, SHOW

I loaded a text file with a huge amount of delimited data to really get a gauge on time this would take. The string is basically, "data%data%data%data%data" and on. Around 600 indexes. I restarted my local instance of SQL Server 2005 that I did these on to ensure you can see CLR before cache and after.

More