пятница, 27 декабря 2013 г.

calling google Url Shortner API in C#

you can check the code below (made use of System.Net). You should notice that the contenttype must be specfied, and must be "application/json"; and also the string to be send must be in json format.
using System;
using System.Net;

using System.IO;
namespace ConsoleApplication1
    class Program
        static void Main(string[] args)
            var httpWebRequest = (HttpWebRequest)WebRequest.Create("https://www.googleapis.com/urlshortener/v1/url");
            httpWebRequest.ContentType = "application/json";
            httpWebRequest.Method = "POST";

            using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
                string json = "{\"longUrl\":\"http://www.google.com/\"}";

            var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
            using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
                var responseText = streamReader.ReadToEnd();



Generate unique strings and numbers in C#

The System.Guid is used whenever we need to generate a unique key, but it is very long. That’s in many cases not an issue, but in a web scenario where it is part of the URL we need to use its string representation which is 36 characters long. It clutters up the URL and is just basically ugly.
It is not possible to shorten it without loosing some of the uniqueness of the GUID, but we can come a long way if we can accept a 16 character string instead.
We can change the standard GUID string representation:
Into a shorter string:
The following method creates the shorter string and it is actually very unique. An iteration of 10 million didn’t create a duplicate. It uses the uniqueness of a GUID to create the string.
private string GenerateId()
 long i = 1;
 foreach (byte b in Guid.NewGuid().ToByteArray())
  i *= ((int)b + 1);
 return string.Format("{0:x}", i - DateTime.Now.Ticks);
If you instead want numbers instead of a string, you can do that to but then you need to go up to 19 characters. The following method converts a GUID to an Int64.
private long GenerateId()
 byte[] buffer = Guid.NewGuid().ToByteArray();
 return BitConverter.ToInt64(buffer, 0);
The standard GUID is still the best way to ensure the uniqueness even though it isn’t 100% unique.

What's the best way to create a short hash, similiar to what tiny Url does?

.NET string object has a GetHashCode() function. It returns an integer. Convert it into a hex and then to an 8 characters long string.
Like so:
string hashCode = String.Format("{0:X}", sourceString.GetHashCode());
UPDATE: Added the remarks from the link above to this answer:
The behavior of GetHashCode is dependent on its implementation, which might change from one version of the common language runtime to another. A reason why this might happen is to improve the performance of GetHashCode.
If two string objects are equal, the GetHashCode method returns identical values. However, there is not a unique hash code value for each unique string value. Different strings can return the same hash code.
Notes to Callers
The value returned by GetHashCode is platform-dependent. It differs on the 32-bit and 64-bit versions of the .NET Framework.

понедельник, 2 декабря 2013 г.

.Config Transformation for projects which are not Web Projects in Visual Studio

I tried several solutions, and here is the simplest I've found.
Dan pointed out in the comments that the original post belongs to Oleg Sychthanks, Oleg!
Here are the instructions:
1. Add an XML file for each configuration to the project.
Typically you will have Debug and Release configurations so name your files App.Debug.configand App.Release.config. In my project, I created a configuration for each kind of enironment so you might want to experiment with that.
2. Unload project and open .csproj file for editing
Visual Studio allows you to edit .csproj right in the editor—you just need to unload the project first. Then right-click on it and select Edit .csproj.
3. Bind App.*.config files to main App.config
Find the project file section that contains all App.config and App.*.config references. You'll notice their build actions are set to None:
 Include="App.config" />
 Include="App.Debug.config" />
 Include="App.Release.config" />
First, set build action for all of them to Content.
Next, make all configuration-specific files dependant on the main App.config so Visual Studio groups them like it does designer and codebehind files.
Replace XML above with the one below:
 Include="App.config" />
 Include="App.Debug.config" >
Include="App.Release.config" > App.config
4. Activate transformations magic
In the end of file after
 Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
and before final
insert the following XML:
   TaskName="TransformXml" AssemblyFile="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v10.0\Web\Microsoft.Web.Publishing.Tasks.dll" />
   Name="AfterCompile" Condition="exists('app.$(Configuration).config')">
     Source="app.config" Destination="$(IntermediateOutputPath)$(TargetFileName).config" Transform="app.$(Configuration).config" />
       Remove="app.config" />
Now you can reload the project, build it and enjoy App.config transformations!
Another solution I've found is NOT to use the transformations but just have a separate config file, e.g. app.Release.config. Then add this line to your csproj file.
   Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
This will not only generate the right myprogram.exe.config file but if you're using Setup and Deployment Project in Visual Studio to generate MSI, it'll force the deployment project to use the correct config file when packaging.
You can use a separate config file per configuration, e.g. app.Debug.config, app.Release.config and then use the configuration variable in your project file:

This will then create the correct ProjectName.exe.config file depending on the configuration you are building in.

Windows Maximum Path Length Limitation

In the Windows API (with some exceptions discussed in the following paragraphs), the maximum length for a path is MAX_PATH, which is defined as 260 characters. A local path is structured in the following order: drive letter, colon, backslash, name components separated by backslashes, and a terminating null character. For example, the maximum path on drive D is "D:\some 256-character path string" where "" represents the invisible terminating null character for the current system codepage. (The characters < > are used here for visual clarity and cannot be part of a valid path string.)
Note  File I/O functions in the Windows API convert "/" to "\" as part of converting the name to an NT-style name, except when using the "\\?\" prefix as detailed in the following sections.
The Windows API has many functions that also have Unicode versions to permit an extended-length path for a maximum total path length of 32,767 characters. This type of path is composed of components separated by backslashes, each up to the value returned in the lpMaximumComponentLength parameter of the GetVolumeInformation function (this value is commonly 255 characters). To specify an extended-length path, use the "\\?\" prefix. For example, "\\?\D:\very long path".
Note  The maximum path of 32,767 characters is approximate, because the "\\?\" prefix may be expanded to a longer string by the system at run time, and this expansion applies to the total length.
The "\\?\" prefix can also be used with paths constructed according to the universal naming convention (UNC). To specify such a path using UNC, use the "\\?\UNC\" prefix. For example, "\\?\UNC\server\share", where "server" is the name of the computer and "share" is the name of the shared folder. These prefixes are not used as part of the path itself. They indicate that the path should be passed to the system with minimal modification, which means that you cannot use forward slashes to represent path separators, or a period to represent the current directory, or double dots to represent the parent directory. Because you cannot use the "\\?\" prefix with a relative path, relative paths are always limited to a total of MAX_PATH characters.
There is no need to perform any Unicode normalization on path and file name strings for use by the Windows file I/O API functions because the file system treats path and file names as an opaque sequence of WCHARs. Any normalization that your application requires should be performed with this in mind, external of any calls to related Windows file I/O API functions.
When using an API to create a directory, the specified path cannot be so long that you cannot append an 8.3 file name (that is, the directory name cannot exceed MAX_PATH minus 12).
The shell and the file system have different requirements. It is possible to create a path with the Windows API that the shell user interface is not able to interpret properly.

пятница, 22 ноября 2013 г.

Simulate a Windows Service using ASP.NET to run scheduled jobs


How do we run scheduled jobs from ASP.NET without requiring a Windows Service to be installed on the server? Very often, we need to run some maintenance tasks or scheduled tasks like sending reminder emails to users from our websites. This can only be achieved using a Windows Service. ASP.NET being stateless provides no support to run code continuously or to run code at a scheduled time. As a result, we have to make our own Windows Services to run scheduled jobs or cron jobs. But in a shared hosted environment, we do not always have the luxury to deploy our own Windows Service to our hosting provider's web server. We either have to buy a dedicated server which is very costly, or sacrifice such features in our web solution. However, running a scheduled task is a very handy feature, especially for sending reminder emails to users, maintenance reports to administrators, or run cleanup operations, etc. I will show you a tricky way to run scheduled jobs using pure ASP.NET without requiring any Windows Service. This solution runs on any hosting service providing just ASP.NET hosting. As a result, you can have the scheduled job feature in your ASP.NET web projects without buying dedicated servers.

How it works

First, we need something in ASP.NET that is continuously running and gives us a callback. The IIS web server is continuously running. So, we somehow need to get a frequent callback from it so that we can lookup a job queue and see if there's something that needs to be executed. Now, there are several ways a web server comes to us:
  • When a page hits
  • When an application starts
  • When an application stops
  • When a session starts and ends/timeouts
  • When a cache item expires
The page hit is random. If nobody visits your website for hours, you can't do the pending jobs for hours. Besides, the execution of a request is very short and needs to finish as soon as possible. If you plan to execute scheduled jobs on page execution, then the page will take longer to execute, which will result in a poor user experience. So, clearly this is not an option.
When an application starts, we get a callback in the Application_Start method of Global.asax. So, this is a good place to start a background thread which runs forever and executes scheduled jobs. However, the thread can be killed anytime the web server decides to take a nap due to zero load.
When an application stops, we get a callback at Application_End. But we can't do anything here because the whole application is going to die soon.
Session_Start in Global.asax is triggered when a user visits a page that requires a new session to be initiated. So, this is also random. We need something that fires consistently and periodically.
A cache item expires on a given time or duration. In ASP.NET, you can add entries in the Cache and set an absolute expiry date time, or you can set a duration after which the item is removed from the cache. You can do this by utilizing the following method of the Cache class:
public void Insert ( System.String key , System.Object value , 
                     System.Web.Caching.CacheDependency dependencies , 
                     System.DateTime absoluteExpiration , 
                     System.TimeSpan slidingExpiration , 
                     System.Web.Caching.CacheItemPriority priority , 
                     System.Web.Caching.CacheItemRemovedCallback onRemoveCallback )
The onRemoveCallback is a delegate to a method which is called whenever a cache item expires. In that method, we can do anything we like. So, this is a good candidate for running code periodically, consistently without requiring any page visit.
This means, we can simulate a Windows Service utilizing Cache timeout! Now, who thought that this would be possible?

Creating cache item callbacks

First, on Application_Start, we need to register a cache item that will expire in two minutes. Please note, the minimum duration you can set for expiring a callback is two minutes. Although you can set a lower value, it does not work. Most probably, the ASP.NET worker process looks at the cache items once every two minutes.
private const string DummyCacheItemKey = "GagaGuguGigi";

protected void Application_Start(Object sender, EventArgs e)
private bool RegisterCacheEntry()
    if( null != HttpContext.Current.Cache[ DummyCacheItemKey ] ) return false;
    HttpContext.Current.Cache.Add( DummyCacheItemKey, "Test", null, 
        DateTime.MaxValue, TimeSpan.FromMinutes(1), 
        new CacheItemRemovedCallback( CacheItemRemovedCallback ) );
    return true;
This cache entry is a dummy entry. We do not store any valuable information here because whatever we store here might be gone on application restart. Besides, all we need is the frequent callback from this item.
Inside the callback, we do all the service work:
public void CacheItemRemovedCallback( string key, 
            object value, CacheItemRemovedReason reason)
    Debug.WriteLine("Cache item callback: " + DateTime.Now.ToString() );

    // Do the service works


Store item in cache again upon expire

Whenever the cache item expires, we get a callback and the item is gone from the cache. So, we no longer get any callback in future. In order to have a continuous supply of callback, we need to store an item in cache again upon expiration. This seems quite easy; we can call the RegisterCacheEntry function shown above from the callback function, can't we? It does not work. When the callback method fires, there is no HttpContext available. TheHttpContext object is only available when a request is being processed. As the callback is fired from the web server behind the scene, there is no request being processed and thus no HttpContext is available. As a result, you cannot get access to the Cache object from the callback function.
The solution is, we need to simulate a request. We can make a dummy call to a dummy webpage by utilizing theWebClient class in the .NET Framework. When the dummy page is being executed, we can get hold of theHttpContext and then register the callback item again.
So, the callback method is modified a bit to make the dummy call:
public void CacheItemRemovedCallback( string key, 
            object value, CacheItemRemovedReason reason)
    Debug.WriteLine("Cache item callback: " + DateTime.Now.ToString() );


    // Do the service works

The HitPage function makes a call to a dummy page:
private const string DummyPageUrl = 

private void HitPage()
    WebClient client = new WebClient();
Whenever the dummy page executes, the Application_BeginRequest method gets called. There, we can check whether this is a dummy page request or not.
protected void Application_BeginRequest(Object sender, EventArgs e)
    // If the dummy page is hit, then it means we want to add another item

    // in cache

    if( HttpContext.Current.Request.Url.ToString() == DummyPageUrl )
       // Add the item in cache and when succesful, do the work.

We only intercept the request to the dummy page, and we let other pages execute as it is.

Restart cache item callback on web process restart

There are several cases where the web server might be restarted. For example, if the Administrator restarts IIS, or restarts the computer, or the web process gets recycled (Windows 2003). In such cases, the service will stop running unless a page is hit and the Application_Start is called. Application_Start is called only when a page is visited for the first time in a web project. So, when the web process is restarted, we need to manually call the dummy page, or someone needs to visit the home page of your website, in order to get the service running again.
One tricky solution to this problem can be adding your website to search engines. Search engines crawl pages frequently. So, they will hit a page of your website, resulting in Application_Start, and thus the service will get up and running.
Another idea is to register your website to some traffic or availability monitoring services. There are lots of Web Services which keep an eye on your website and checks whether it is alive and the performance is satisfactory. All these services hit your web site pages and then collect the statistics. So, by registering in such services, you can guarantee your web application is alive all the time.

Testing possible types of job executions

Let's test whether we can do all possible tasks that we can do from a Windows Service. The first problem is, we cannot do everything a Windows Service does because it runs in the Local System account. This is a very high privilege account, and you can do anything to your system under this account. However, the ASP.NET web process runs in the ASPNET account (Windows XP) or NETWORK SERVICE account (Windows 2003). This is a low privilege account, and does not have the right to access the hard drive. In order to allow the service to write to the hard drive, the web process account needs to be allowed write permission to a folder exclusively. We all know about this security problem, so I won't go into details about it.
Now, we will be testing all possible things that we normally do from a Windows Service:
  • Write to a file
  • Database operations
  • Web Service calls
  • MSMQ operations
  • Email send
Let's write some test code for this inside the DoWork method:
private void DoWork()
    Debug.WriteLine("Begin DoWork...");
    Debug.WriteLine("Running as: " + 
          WindowsIdentity.GetCurrent().Name );


    Debug.WriteLine("End DoWork...");

Testing file write

Let's test if we can really write to a file. Create a folder named “temp” in your C drive, and if the drive is an NTFS partition, allow the ASPNET/NETWORK SERVICE account to write to that folder.
private void DoSomeFileWritingStuff()
    Debug.WriteLine("Writing to file...");

       using( StreamWriter writer = 
        new StreamWriter(@"c:\temp\Cachecallback.txt", true) )
        writer.WriteLine("Cache Callback: {0}", DateTime.Now);
    catch( Exception x )
       Debug.WriteLine( x );

    Debug.WriteLine("File write successful");
Open the log file, and you should see entries like:
Cache Callback: 10/17/2005 2:50:00 PM
Cache Callback: 10/17/2005 2:52:00 PM
Cache Callback: 10/17/2005 2:54:00 PM
Cache Callback: 10/17/2005 2:56:00 PM
Cache Callback: 10/17/2005 2:58:00 PM
Cache Callback: 10/17/2005 3:00:00 PM

Testing database connectivity

Run the following script in your “tempdb” database inside SQL Server 2000:
IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = 
    object_id(N'[dbo].[ASPNETServiceLog]') AND 
    OBJECTPROPERTY(id, N'IsUserTable') = 1)
DROP TABLE [dbo].[ASPNETServiceLog]

CREATE TABLE [dbo].[ASPNETServiceLog] (
    [Mesage] [varchar] (1000) 
    COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL ,
    [DateTime] [datetime] NOT NULL 
This will create a table named ASPNETServiceLog for you. Remember, as it is created in tempdb, this table will disappear when SQL Server restarts.
Next, make the ASPNET/NETWORK SERVICE account a member of db_datawriter of the tempdb database. Alternatively, you can define a more specific permission and allow only writing to the table.
Now write the test function:
private void DoSomeDatabaseOperation()
    Debug.WriteLine("Connecting to database...");

    using( SqlConnection con = new SqlConnection("Data Source" + 
           "=(local);Initial Catalog=tempdb;Integrated Security=SSPI;") )

        using( SqlCommand cmd = new SqlCommand( "INSERT" + 
               " INTO ASPNETServiceLog VALUES" + 
               " (@Message, @DateTime)", con ) )
            cmd.Parameters.Add("@Message", SqlDbType.VarChar, 1024).Value = 
                               "Hi I'm the ASP NET Service";
            cmd.Parameters.Add("@DateTime", SqlDbType.DateTime).Value = 



    Debug.WriteLine("Database connection successful");
This will create entries in the log table, which you can check later on to ensure if there was any delay between the service execution. You should be getting one row per two minutes.
Service Log File
Figure 1: ASP NET Service Log Table Data

Testing email delivery

The most common requirement for running a Windows Service is to send periodical email alerts, notifications, status reports, etc., via mail. So, it's important that we test if email works from such a service:
private void DoSomeEmailSendStuff()
       MailMessage msg = new MailMessage();
       msg.From = "abc@cde.fgh";
       msg.To = "ijk@lmn.opq";
       msg.Subject = "Reminder: " + DateTime.Now.ToString();
       msg.Body = "This is a server generated message";
       SmtpMail.Send( msg );
    catch( Exception x )
       Debug.WriteLine( x );
Please replace From and To recipient addresses with some meaningful address, and you should be getting email alerts every two minutes.

Testing MSMQ

Let's write a small function to test whether we can access MSMQ from ASP.NET properly:
private void DoSomeMSMQStuff()
    using( MessageQueue queue = new MessageQueue(MSMQ_NAME) )
Alternatively, you can call the Receive method of the queue to get pending messages in the queue that needs to be processed.
One issue that you should remember here is, do not subscribe to the Receive event of the queue. As the thread can die anytime and the Web Server can be restarted anytime, a continuous blocked Receive will not work properly. Besides, if you call the BeginReceive method and block code execution until a message arrives, the service gets stuck and other codes will not run. So, in this case, you will have to call the Receive method to fetch the pending messages.

Extending the system

The ASP.NET Service can be extended in many ways to allow pluggable jobs. You can introduce Job queuing from web pages which this service will execute periodically. For example, you can queue jobs in a cache item and the services pick up the job and executes it. This way, you can simulate a nice job processing system inside your ASP.NET project. Previously, this was only possible with a Windows Service, but now you can do it with ASP.NET also.
Let's make a simple Job class which contains information about a job to execute.
public class Job
    public string Title;
    public DateTime ExecutionTime;

    public Job( string title, DateTime executionTime )
        this.Title = title;
        this.ExecutionTime = executionTime;

    public void Execute()
        Debug.WriteLine("Executing job at: " + DateTime.Now );
From a simple ASPX page, we will queue a job to a static ArrayList called _JobQueue declared in Global.asax:
Job newJob = new Job( "A job queued at: " + DateTime.Now, 
                      DateTime.Now.AddMinutes(4) );
lock( Global._JobQueue )
    Global._JobQueue.Add( newJob );
So, the job gets queued to be executed after 4 minutes. The service code runs every two minutes and checks the job queue if there's anything that is overdue and needs to be executed. If there's any job waiting, it is removed from the queue and executed. The service code now has an additional method called ExecuteQueuedJobs. This function does the scheduled job execution:
private void ExecuteQueuedJobs()
    ArrayList jobs = new ArrayList();
    // Collect which jobs are overdue

    foreach( Job job in _JobQueue )
       if( job.ExecutionTime <= DateTime.Now )
        jobs.Add( job );

    // Execute the jobs that are overdue

    foreach( Job job in jobs )
       lock( _JobQueue )
        _JobQueue.Remove( job );

Don't forget to lock the static job collection because ASP.NET is multithreaded, and pages being executed on different threads have a high possibility for trying to write on the job queue at the same time.

Who can benefit from this

ASP.NET developers who host their website on shared hosting environments which do not offer a Windows Service feature can benefit from this code. Also for those who do not have their own dedicated server to install Windows Services.

How to run the sample project

The sample project is a very simple website with a dummy page. All the code is inside Global.asax. You need to modify the connection string, MSMQ name, and the folder path according to your settings.
Here's how to setup the code:
  • Extract the zip in a folder.
  • Create a virtual directory named "TestCacheTimeout" and map to the extracted folder.
  • Load the project file and run.
  • Create an MSMQ Queue called "ASPNETService".
  • Run the SQL to create the log table in tempdb, as explained earlier.
  • Create a temp folder in C: drive and add the ASPNET/NETWORK SERVICE account with Write permission.
  • Fix all the constants available in Global.asax.
If you want to add the code in your own project, do the following:
  • Copy the Global.asax code to yours.
  • Create a dummy page which queues the cache item. The dummy page needs no code.
  • Modify the constants available in the Global.asax at the beginning.