Wednesday, October 03, 2007

Firstable, before I am going to write the following words, I want to mention and admit that I am realy a big fan of Microsoft technologies, its innovetions and its line of philosophy; Most of the time they are doing good job (in some cases I would implement some things in other way, but this issue if for other post...).

What I want to talk about in this post is the C# language's development from the first version of .NET until the further to come which is .NET 3.5 in Visual Studio 2008.
In the beginning of .NET 2.0 there were great and major language improvement, like generics, anonymous methods/delegates and more nice things (that indeed, helps us to write more nice, agile and elegant code). BUT major things often require new keywords to support the 'enhanced' language, for an example: the <TEntity> syntax in order to use and implement generics.

In the generics case, this syntax is required in order to make a usage with this great feature, but in most cases new keywords are BAD, just bad because developers have the annoying habit of using non-keywords as identifiers. An example for new keyword is the pair: return yield. In the first version of iterators, you had to use yield when you wanted to "return" an iterator value back, and as we know everything worked just fine, so why should they need to add the return keyword in order to return the iterator's value? (I'll be glad to get the answer if you got it...)

I tried to figure out and see what Microsoft tried to do regarding this issue and found that they ment to provide a utility that you could run over your source code, and it would replace any identifier that had become a keyword with the escaped version. It should do this by putting an "@" sign in front of it. I don't think that tool at least was published...

Today, just before .NET 3.5 is releases out (not in beta of course), we can see on beta versions and examples the new keywords and innovations that had been added to the language which demands from us to adjust ourselves to the new syntax.

At the bottom line, it makes us a little bit of hard time at the begining, but it enhances our language and gives us a learning challenge and the ability of upgrading our code (maybe not easy to read on the first time but easy to implement and to make it more agile and generic). 

;-)I encourages these changes, but don't forget - everything could work just fine without these new stuff.

C# | Code | Other
Posted by: Eran Nachum (c)
Post Date: 10/3/2007 11:34:29 AM (Jerusalem Standard Time, UTC+02:00)
Disclaimer | Comments [1] | Trackback   #
 Monday, September 24, 2007

As I posted in the last post, I didn't have much time to update my blog last month (even most of this month), so I hope I could catch up these days and post some more about the on going issues that comes up.

Last month, a gut named Roni Schuetz send me an email regarding my post about Maintaining Data over Multi-Servers (Load Balancing on Web Farm) (direct link here).
Roni is the creator of a project named, Shared Cache which supplies high-performance, distributed memory object caching system, generic in nature, but intended to speeding up dynamic web and / or win applications by alleviating database load. He suggested me to use his project regarding maintaining cached data between multiple servers and I acceded testing it.

By Roni's documentation and project usage explanations the project is friendly usable and for a free-to-use-software I think it is highly recomended using it (or at least testing it).

Unfortunatly (or not), my company (IDT Global) has purchased (an expensive and also a great one) tool called ScaleOut SessionState In order to maintain session data over multiplae servers.

So, if you have an answer regarding this issue or just want to read about it, you can try Roni's indeXus.Net Shared Cache here.

Posted by: Eran Nachum (c)
Post Date: 9/24/2007 10:15:21 AM (Jerusalem Standard Time, UTC+02:00)
Disclaimer | Comments [0] | Trackback   #
 Sunday, September 23, 2007

Long time no post, I know... I have some stress at work these couple weeks, we need (I need*) to go on QA these days with the first step of the on working application (doing now some unit tests).

I ment going to Roy Osherove and Danko meeting regarding Agile and Scrum Planning but it didn't turn out, so I listened it through Roy's blog. I must say that I very enjoyed it and there were some things that actually match some of my cases regarding my working.

I Involved with some things that were said there but the most one is the distance issue. I am leading technologicly the web application that we are working on, and the rest of my team (2 software programmers and a project manager) are sitting in the US (Newark). Every evening (my evening - their morning) we are doing a conference meeting, sometimes on phone and sometimes on video and discussing the problems we bumped in, schedules, missions and some code reviews, this meeting is quite good and enable us to catch up on each other and to try manage the process of the working application.

BUT, this distance has a price! This price comes to fruition by time. Sometimes when I have some questions regarding the project spec, or just simple questions that I could get a quick answer from the project manager, I need to note'em and to send an detailed email regaring it.

Roy talked about it in his Scrum meeting introduction and said: "Keep team together, side by side, not even in seperate floors or rooms" and I think it's true, but like every project or something else in life anything has adventages and disadventages; This distance helped me to understand better the flow logic of the application, its functional specifications and more.

So, I'll try to bring in some more Scrum points into my team and project management...

Posted by: Eran Nachum (c)
Post Date: 9/23/2007 12:01:42 PM (Jerusalem Standard Time, UTC+02:00)
Disclaimer | Comments [0] | Trackback   #
 Wednesday, August 15, 2007

After squeezing pandora radio from all sides (and songs ;)), I discovered a great internet radio website, called: bee.fm.

The greatest thing about this site is the ability of listening almost all (and whole) albums of the chosen artist. So, if you are music fans, that like to listen to great music while working, this is the site for you (and NO, I am not getting from them any comission ;)).

So, cheers by now... I going back to listen some Frank Sinatra, Alice in Chains, Pearl Jam, Jetru Tull, Madonna, Sade and more and more...

Posted by: Eran Nachum (c)
Post Date: 8/15/2007 4:23:39 PM (Jerusalem Standard Time, UTC+02:00)
Disclaimer | Comments [3] | Trackback   #
 Monday, August 13, 2007

Every site (or site admin in that case) desires to serve the users that are visiting the site on the best way, handle the traffic situation on the best side (if doesn't it's annoying the user and there is a chance that they won't come again).

Well known solution to this problem is to hold two (or more) servers needed to handle user requests. The main idea behind this web farm is to share pooled resources. There is a need to hold a common front end dispatcher to perform load control and manage customer requests.

My working web application answers these criterions mentioned above, it should be serving hugh amount of clients, therefore there is a usage of multi servers to give the best outcome, and I had to deal with that situation...

There several approach to deal this 'problem' that I could think of and listed ahead:

Session Management

There are 2 solutions supplied by ASP.NET regarding sharing state information between multiple servers:
State Server - In the specific web farm, you must approve that each web server holds the same <machinekey>. On the second step, if we'll want to maintain the session state across the web servers, each website's application path in the IIS metabase should be the same in the web farm.
One more important thing is to make sure of all the objects should (that you want to store in the session of course) be serializable (remember previuos post?).

SQL Server - Although I am using Oracle Database to store the current application data, I just wanted to mention this solution and will expand some basic details about this solution; Firstable, you should make sure all the objects are serializable, and like before, each website's application path in the IIS metabase should be the same in the web farm. This solution requires some SQL Server configuration in order to maintain the session management. You can read about it in more details here and here. Some very important security issues that you must consider are:

  • Don't forget to encrypt your connection string (stored in the web.config or somewhere else).
  • Use Windows authentication to the database and limit the application's login in it.
  • Run the application in a secure channel.

Machine Authentication Check (MAC)

This solution comes for maintaining the form's information after firing events that are causing server postback. If you are working on one webserver, well... everything will act just fine; A common user behavior will fire a postback event which will go back to the server and deal with the sent data. BUT, what will happen if the event's data will be posted to another webserver? (All data will be lost...)

To solve this 'problem' you should modify the pages element in the machine.config of each webserver and set the enableViewStateMac attribute:

<system.web> 
   <pages enableViewStateMac="false" />
</system.web>

This will mention that the process should run a machine authentication check (MAC) on the pages' view state when the page is posted back from the client; true if the view state should be MAC checked and encoded; otherwise, false. The default is false.
"A view state MAC is an encoded version of the hidden variable that a page's view state is persisted to when sent to the browser. When you set the EnableViewStateMac attribute to true, the encoded and encrypted view state is checked to verify that it has not been tampered with on the client." (from MSDN).

Data Caching

  • Shared Cache Application -You should use a cache application in order to cache you application's data. A good solution is to create am application that will be place in a single location. Each application (or each webserver) will send its data to this cache application to be cached. Each data retrieval will requested from the cache apllication firstly, otherwise will grab it from the specific data source (database etc...).
  • SQL Server Caching - You can cache the data into Sql Server, it's quite easy to apply using ADO.NET and the .NET Framework provides a common development model to use with existing data access components. You can read some details about it here. Since in most case there is a single database that holds the data, you can use this kind of solution.

These are some of the ways for maintaining data over multi servers. I will be glad to hear about some more solutions and ways...

Posted by: Eran Nachum (c)
Post Date: 8/13/2007 8:07:55 AM (Jerusalem Standard Time, UTC+02:00)
Disclaimer | Comments [2] | Trackback   #
 Monday, August 06, 2007

Post Prolog: Out of the record, as a continues to the previous post, I want to say that I am enjoing my life as a father, if I had know it I would do it earlier, BTW the little one named by my wife and me as Ori. More pics will be publish soon...)

Now, to this post issue...

I bumped in on a strange scenario; In my current working application, I have a page that holds a repeater that displays some data. This data is being declared in each partner's web.config's configSection. In order to read it once, I set this custom object as a Serializable one (which implements the ISerializable interface of course) and saved it into the ViewState of the page.

Now, when reading this object and saving it into the ViewState, everything has worked just fine (the server serialized this data properly).
But, when trying to grab this data from the ViewState (de-serialize this data) an annoying and vauge error message has been displayed was saying that: "The state information is invalid for this page and might be corrupted".

After a long and frustrating research about it, it turns out that the server will have NO KNOWLEDGE of the assembly name (Note: It was randomly generated when your site compiled on first run) because its own version of that assembly will have been compiled with a completely different random name, and it will not be able to de-serialise the viewstate and get the requested data.

To get around this problem, we should AVOID PLACING custom types into the viewstate (place'em somewhere else, like session, application etc.).

If you've got some more complex objects (or some custom types), these will need to be moved into a seperate class library project that is pre-compiled before deploying to the web-server. By doing it, it can be ensured that every web server has a copy of the same assembly and that the assembly has the same signature/name!  Try to avoid creating custom types in your App_Code or any of your web site files.  Rather create custom types in their own project to be compiled into a seperate assembly.

Cheers by now...

Posted by: Eran Nachum (c)
Post Date: 8/6/2007 2:25:07 PM (Jerusalem Standard Time, UTC+02:00)
Disclaimer | Comments [0] | Trackback   #
 Thursday, July 19, 2007

I'd like to represent my new son that was borned this Tuesday, July 17, 2007 05:55 AM at Jerusalem, Israel. Name has not yet been given and will be revealed at the Brith :)

It's more to come...

Posted by: Eran Nachum (c)
Post Date: 7/19/2007 12:59:06 PM (Jerusalem Standard Time, UTC+02:00)
Disclaimer | Comments [9] | Trackback   #
 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 | Comments [0] | Trackback   #