Tuesday, July 10, 2007

I am working against 3rd level party assembly in my current web application. I need to send US address information to this assembly and to retrieve an answer whether this address is exist or not. This assembly requires validation against X.509 certificate (to ensure that only permited client could use the 3rd level's services), which is installed on the server that runs the application (in dev environment this is my local PC).
More details about it here.

The problem: In order to authenticate against this certificate, the process that runs the application need to 'hold' sufficient credentials in order to get an access to the certificate and to do the authentication. Here comes our problem; when trying to access this certificate through the asp.net application, we run into a problem - It's impossible, because the process that runs the web application is ASPNET and doesn't has the needed credentials in order to authenticate the certificate and get the info from the 3rd level.

Suggested solutions:

  1. Credentials. Read the credentials from the web.config (username, password and domain) and impersonate the user using these credentials. This will 'save' the impersonated user all over the impersonation context (System.Security.Principal.WindowsImpersonationContext) and the authenicate action against the certificate will be done using this credentials. One more important thing, to ensure this data protected, encrypt it before puting it into the web.config.
  2. I thought about IIS Application Pool. This is a great feature that came up in IIS 6.0, which enables you the ability of creating one or more applications and allows us to configure a level of isolation between different Web applications. You can set the identity of an application pool which will be the account under which the application pool's worker process runs. So I thought to set it over there, but I had one big problem, an IIS 5 was installed on the production server and it is not a dedicated server. (More details about application pool here).
  3. Host .NET component in COM+. This is the third solution and the best for me at the current circumstances; Because I am working with a several applications (assemblies) I want to host the component that validates the user against the 3rd level party, this will give me a unified behavoir for all the applications while doing this action (Instead of setting these properties in web.config file of each web application we want to use {solution 1, remember?}). In other words, I'll set the username and password on the COM+ component just once in order to grant the process that runs this component the right and sufficient credentials. .NET provides a way to host your .NET components inside COM+ environment. All the functionality you need to write a COM+ aware component in .NET can be found in System.EnterpriseServices namespace.

So how we do it (hosting .NET assembly in COM+)?

Take a look on this code:

using System;
using System.Collections.Generic;
using System.Text;
using System.EnterpriseServices;
using System.IO;
using System.Reflection;
using System.Runtime.InteropServices;

namespace ComPlusTest
{
    [Transaction(TransactionOption.Required),
        ObjectPooling(MinPoolSize=2, MaxPoolSize=5, CreationTimeout=20000),
        ComVisible(true)]
    public class TestClass : ServicedComponent
    {
        protected override void Activate()
        {
            base.Activate();
            DoSomeAction(Action activate)
        }

        protected override void Deactivate()
        {
            base.Deactivate();
            DoSomeAction(Action deactivate)
        }

        protected override bool CanBePooled()
        {
            DoSomeAction(Action pooled)
            return base.CanBePooled();
        }

        public void ValidateAddress(string address)
        {
            try
            {
               // Do the validation against the 3rd party
               ContextUtil.SetComplete();
            }
            catch(Exception ex)
            {
               // Handle exception
               ContextUtil.SetAbort();
            }
        }

        [AutoComplete()]
        public void JustAction()
        {
            DoSomeAction(Action simpleAction);
        }

        private void DoSomeAction(Action act)
        {
            // Do the action
        }
    }
}

Lets dissect it:

  1. Firstable you can see that the class is derived from ServicesComponent (which sits in the System.EnterpriseServices namespace). I marked our TestClass with some attributes. The first one in Transaction; The values for this attribute are same as in traditional VB/VC++ development i.e. Required, RequiresNew, Supported etc. MinPoolSize and MaxPoolSize specifies values for minimum and maximum object instances. The ComVisible attribute must be set to true to give the accessibility of an individual managed type or member, or of all types within an assembly, to COM (I spent lots of time trying to figure out some exceptions that I had while overriding the ServicesComponent class).
  2. the class is marked to require a transaction each method will execute in a transaction (existing or new). Once the ValidateAddress has been executed we need to either commit or rollback the transaction. This is done via static methods of ContextUtil class. The method SetComplete is used to commit a transaction where as SetAbort is used to rollback a transaction.
  3. Just for example, I defined a methid called JustAction. This method is marked with an attribute AutoComplete which means that once the method execution is over the transaction is automatically committed (equivalent to ContextUtil.SetComplete). In case of any error the transaction will be rolled back (equivalent to ContextUtil.SetAbort).
  4. Overrided Activate, Deactivate and CanBePooled methods are just for testing (in order to observe the flow behavior).

Now, you have to sign your assembly with a strong name and to add the following attributes to the AssemblyInfo class of your project:

[assembly: ApplicationName("ComPlusTest")]
[assembly: ApplicationActivation(ActivationOption.Library)]
[assembly: AssemblyKeyFileAttribute("ComPlusKey.pfx")]

Posted by: Eran Nachum (c)
Post Date: 7/10/2007 4:49:24 PM (Jerusalem Standard Time, UTC+02:00)
Disclaimer | | Trackback   #
 Monday, July 09, 2007

I know it's maybe a little bit banal, but Tzippi (my beloved wife) wanted me to publish it, so here it is:

Egozi, Oren, Dror, when do we make avatars union?

Funny | Other
Posted by: Eran Nachum (c)
Post Date: 7/9/2007 10:54:48 AM (Jerusalem Standard Time, UTC+02:00)
Disclaimer | | Trackback   #
 Wednesday, July 04, 2007

I got an email the other day from Omer Rauchwerger, the developer and the man who stands behind a nice tool (addin that runs over the Visual Studio 2005) called Regionerate. I had requested to 'play' with this tool and give an opinion about it, and so I did...

(Note: I heard about it earlier than Omer's email, Ken Egozi's had posted about it on his blog).

Before I outlines my impressions, comments and feelings about it, I want to give some words about the Regionerate website itself; The man did here realy good job. There are great detailed demo movie that displays the work of the tool, some tutorials, gallery and more...

About the tool, well I'd downloaded the latest version (beta) on my PC and played with it a little bit. The usage is very convinient and indeed saves time while reagioning your code, it all being done by a single right click and gives nice and elegant outcome.

I very impressed from the custom Code Layout of this tool; By Using this tool you can customize your final layout of code by simple XML file editing (fully intellisense adapted).

On the  end of the day, a great work has been done here and I am looking for more innovetions in the next versions and for the final release of course.

Omer, if you'll find a way to give the ability of titling each specific region in addition to the current titles (before regioning of course) it will be great one.

Download is here.

Posted by: Eran Nachum (c)
Post Date: 7/4/2007 8:44:49 AM (Jerusalem Standard Time, UTC+02:00)
Disclaimer | | Trackback   #
 Sunday, July 01, 2007

I had a performance problem in my current working on web application; In one of my flows in this application, I had needed to call the database and to update some large amount of data over there, but this action had taken lots of time and the outcome was that users had to wait a long time until this action will be done, admit it, it is frustrating...

My first kind of solution to this problem was to create a new thred from the IIS's thread pool and to assign this action under it - quite good resolution not? BUT, I reminded that asp.net 2.0 (also 1.X) already implements it in a better and friendly way, using Asynchronous Pages.

But first, some Background...
As we all know (or not), when ASP.NET receives a request from the user, it ask for a thread from a thread pool and assigns that request to the thread. In order to this action, the synchronous page holds this thread for the duration of the request, and preventing it from being used by other requests. That leads us to my problem: when I am calling to the database and doing the long long action (an UPDATE query), the thread assigned to the request is stuck doing nothing until the call returns. (This happens because the thread pool has a finite number of threads available).

The Resolution is (of course) Asynchronous Pages.

Asynchronous pages offers a neat solution to such kind of problems. Once an asynchronous operation begins in response to a signal from ASP.NET, the page returns the used thread to the thread pool. When this operation completes, this mechanism asks for another thread from the thread pool and finishes processing the request. This mechanism helps us to manage more efficiently the threads manipulation from the thread pool, because threads that were stucked earlier, now can be used for other porpuses.

Lets see some code:

Firstable, you need to set the Async property on the top on the asp.net page in order to use this thing:

<%@Page Language="C#" Async="true" ... %>

This property set to true, says the page to implement the IHttpAsyncHandler. Regarding this, you need to register the Begin method and End method of to the Page.AddOnPreRenderCompleteAsync.

// Register async methods
AddOnPreRenderCompleteAsync(
   new BeginEventHandler(BeginAsyncOperation),
   new EndEventHandler(EndAsyncOperation)
);

By these actions, the starts its normal life cycle, until the end of the OnPreRender event invocation. At this point the ASP.NET calls the Begin method that we registered earlier and the operation begins (calling the database etc...), meanwhile, the thread that has been assigned to the request goeas back to the thread pool. At the end of the Begin method, an IAsyncResult is being sent automatically to the ASP.NET and let it determine in the operation had completed, a new thread is being called from the thread pool and there is call to the End method (that we registered earlier, remmember?).

Note: We do not need to implement the IAsyncResult interface, the Framework implements it for us.

The Begin and End Methods:

IAsyncResult BeginAsyncOperation (object sender, EventArgs e, AsyncCallback cb, object state)
{
   // Do your things...
   // Call the DB and run the long long query...
}

void EndAsyncOperation(IAsyncResult ar)
{
   // Do your things...
   // Get a response from the DB that the operation is DONE...
}

Nide ahhhu? So use it wisely...

Posted by: Eran Nachum (c)
Post Date: 7/1/2007 11:26:35 AM (Jerusalem Standard Time, UTC+02:00)
Disclaimer | | Trackback   #
 Thursday, June 21, 2007

I had a debate (friendly one of course...) with a co-worker of mine, called Maayan. We discussed about what is the best place to save quite large of data that need to be used frequently in my web application, should we store it in the Application object or the prefered way - store it in the Cache object?

Before we'll go to the conclution, lets get some details about these 2 terms and the vast term called Caching in applications.

2nd before - I am not going to invent the wheel on this post, just to sharpen some points that I think that are missing or came up for most of us...

Caching is the most effective technique you can use to improve the performance of your ASP.NET web application. Designing your application with caching in mind, improves both the performance and the scalability of that application. Caching is about storing data in memory the first time it is requested and then re-using it for the following requests for a specified period of time.

ASP.NET provides very convenient API in order to use this term for the best and easy way, reffered also to Application data object and Output Cache of course.

You can cache the application data using the System.Web.Caching.Cache class. One instance of this class is created per application domain, and it remains valid as long as the application domain remains active. This object is global which means its data is avaiable anywhere at the application scope.

Now, to the big question: What is more recomended for storing the data, Cache object or Application object?

Well, the main difference between them is that he cache object has some more powerful features that allows you to control the cached data. Which this object, each of the data item has its priority state and expiration time. This object has 2 important issues handling: When your system's memory becomes short, the chache object knows to remove data items with low priorety and free its memory, by that the cahce ensures that unnecessary items does not consume valuable server resources.

One more good adventage (in ASP.NET of course) is to cache the pages' data. ASP.NET allows you to cache web pages or portions of them, calling this an output caching. By caching frequently requested pages or portions of them, you can substantially increases your web server throughput and get a fast page response. You can cache pages on devices like: the web browser making the request, the web server responding to the request, and any other cache capable devices such as proxy servers. To read some more information about it go here).

Conclution: I think that for more complex data manipulation caching, the recommended way is to use the cache object and API, but if you want to use and cache some 'dummy' data (or just data that not has to be modified and managed during the application), use the application object (or session object - per user's session) to chach your data.

Posted by: Eran Nachum (c)
Post Date: 6/21/2007 5:12:40 PM (Jerusalem Standard Time, UTC+02:00)
Disclaimer | | Trackback   #
 Monday, June 18, 2007

I sat yesterday in front of my big screen LCD TV at home, and I must tell you that I've enjoyed every step on the game between Real Madrid and Mallorca.

1456 days - this is the time that had pass from the last Real's championship until yesterday evening. After a great comeback from the men in white, (3:1 on Mallorca), this club earned his 30th championship. Until the 79th minute of the game, Barca (the previous champion) was virtually saved its title, but of course Capello's team did the unbelivable, the substitue - Rayas ripped the net twice and lead the men in white to its championship.

I am glad and think that it's a good refreshment (Barca had become a little bit boring...), after all the Spanish league is the best, don't you think?

 (A.P)

Posted by: Eran Nachum (c)
Post Date: 6/18/2007 10:25:38 AM (Jerusalem Standard Time, UTC+02:00)
Disclaimer | | Trackback   #
 Wednesday, June 13, 2007

I know that I am a big fan of Microsoft products and technologhy, but I read today the Safari (from Apple) is ready to download.

Despite this version is still a beta, you can download it to your PC and start playing with it.

I downloaded it just to get the feel impression of it and also to has an idea how my web applications are being showed there... (good for cross browsers suitabilities). And it's nice...

Download is here.

Posted by: Eran Nachum (c)
Post Date: 6/13/2007 8:39:59 AM (Jerusalem Standard Time, UTC+02:00)
Disclaimer | | Trackback   #
 Sunday, June 10, 2007

These days I am working on a very big web application...

In one of my aspx pages I had needed to save lots of data in the ViewState object in order to persist data between postbacks, but when I looked at the rendered HTML, I saw a large hidden field for carring the ViewState.

ASP.NET 2.0 came up with a new feature that helps to reduce the amount of the hidden filed's ViewState data that called: PageStatePersister.

When we add an override the PageStatePersister property and use the built-in SessionPageStatePersister, the behavior of the page remains the same, but the storage used for the bulk of the state data is shifted from the hidden field to session state.

Implamantation instance:

protected override PageStatePersister PageStatePersister
{
   get { return new SessionPageStatePersister(this); }
}

In several cases you'll only want to override this property in your page and to shift the ViewState data into the Sesson object, but if you'll want to use it (wisely of course) on your entire web application? You should implement this property in a particular custom base page and to inherit it to all of your application pages.

The only disadventage that I could think about here is the data existent, session can lose its data and information if its timeout has ended, but ViewState can hold the data forever on the page, because it's hard coded.

Posted by: Eran Nachum (c)
Post Date: 6/10/2007 3:08:17 PM (Jerusalem Standard Time, UTC+02:00)
Disclaimer | | Trackback   #