# Saturday, October 08, 2005

If you haven't seen this before, pay this link a visit;
It contains a list of useful things you can use via google search engine in order to optimize your searches.
   

Posted by Oren Ellenbogen 
08/10/2005 01:06, Israel time UTC-07:00,     Comments [1]  | 
# Friday, October 07, 2005

I've just landed this morning in our too-big-too-much-to-walk Ben-Gurion airport from my one week vacation at the beautiful Paris. To be honest, I really needed this vacation, I had too much on my mind during the last couple of months - University planning, work (and lots of it) and some universal (we called it "in-romo-shel-olam" in Hebrew) decisions to think about like my near future goals which I love to think about every new year. Meeting my great family, having some 20 folks dinner with amazing food and lots of good wine can do wonders to your mind and body so I come back with some new powers which I'm sure I'll need in order to progress during this new year.

I picked some insights during this week, some of them I would like to share with you -

Controlling the arm rest in the airplane as a life story.
On my way back, I flew with Arkia Boeing 757, meaning 3 seats in each side of the airplane; Guess what, I had to sit in the middle, between my father and another problematic guy. Why problematic ? I knew you'll ask it, well that's because he always tried to take over my arm rest and kept me awake for 4 damn hours and 5 minutes ! You can't blame me that I haven't tried, I tried to push, to take only the bottom side of the arm rest, only the upper side of the arm rest, to stretch while trying to take over, EVERYTHING ! this guy was persistent ! Well, I'm sometimes more stubborn than necessary, but I saw that this battle wasn't for me to win so I took the battle into a field I knew I can win - the arm rest near my dad. Don't give me that poor smile and nodding, if you try to move the man while he's a sleep, you must come with some heavy armor. The problem was that he was sleeping(\reading, he turned the pages in his book every 2-10 minutes) and I didn't want to move his hand. But... every child knows his parents' weak points and in my father's case it's me. Moving a little bit in my chair and showing him I'm a little bit tired (=unhappy) gave us both a great idea. In a sweep move, my father asked the fellow beside me to get up as he needed to go to the toilet. I had to get up too, but it's LIFO(last in, first out) style, so I had the position before him; Man, I love good tactics. So after 4 hours and 5 minutes, we had left only 10 minutes in the air so my trick was a little bit useless and I couldn't sleep at all, but I think I've learned a lot from it, don't you ?

Arm rests should come in couples for the chair in the middle in 3 sits airplanes.
See the section above. I think I should write a patent on this one, this is gold.

Take yourself some time to think about your goals in the near future, new year holiday is good time IMHO.
This year will be an important year for me, like any other year in our short life but maybe just a little bit more. This year I hope to start on the right foot (and hand, for that manner) my academic course and to step up in my work. In addition I'm planing to release a mini "product" out to the world and to see(and learn) how it goes. Well, you're all familiar with those subjects (work, studies) but they are too big to think over without decomposing them into more feasible tasks. I started my thinking during the vacation and I promised myself to finish up (and "refactor") during the next week.  So, I tried to decompose my "I want to improve at my work" task into smaller tasks like (just a small part from my tasks list):

  1. I want to improve my management skills
    1. I want to learn some time-management tools (so I'll be able to complete the next section).
    2. I want to build my teammates schedules.
    3. I want to follow it with them so I would be able to understand better where do they "waste" time so I can avoid it or think about ways to improve it. I want to be able to detect good progress and good work so I could praise them and make sure that this good phases(\methods) will be longer on their next assignments.
    4. I want to be able to teach my teammates - I really believe that good workers(and human beings for that manner) are those that aren't afraid to say that they want to learn new things every day even if that means they'll have to change their work every X years. I want to be able to teach my teammates a thing or two, direct them to other resources so they'll be able to learn, or any other media so they'll be happy to come to work every morning.
  2. I want to be taught - I'm trying to be a good worker, so section 1.4 must apply to me also. In order to do that I must think about ways to learn and set my mind about the subjects that interesting me; Finally, I have to sit with the people in my company(or surroundings) which I think has the capabilities to teach me and think how can I convince them that teaching me will be beneficial for them as well.
  3. I want to improve my software analyzing capabilities - I want to think and participate in the design of 2 huge softwares we're about the develop.
  4. I want to improve my selling skills - I'm thinking about releasing a small software with a friend of mine and in the last couple of days I'm thinking more and more if to release it as open-source or maybe trying to sell it as a product. I want to insert new technologies(.net 2, sql server 2005 and more) to my company, I must figure a good plan in order to do this smoothly and to justify any changes in our development phases so the management could be relaxed and fully understand why this changes will result "win-win" situation.
  5. I want to finish this year university courses with good success (85+ avg.) - The degree is important and I don't want to let it go just because I'm working, and I can plan my time better so I would be able to work and study at the same time without neglected any one of them, it's up to me, like always.
This is just the tip of the iceberg from my original list, but I think you get the idea. I'm planing to build this kind of list in my office so my teammates would be able to tell me their work expectations for this year and I would be able to think about ways which I can help them to achieve it.

Don't be afraid to let the world know - "I want" to do this, this and that !
Almost all the people I know want to be rich for many well known reasons. The problem in my opinion is not the "rich dad, poor dad" issues of "we're been taught to be humble about our desires, to be satisfied with our average paycheck" etc. It's the lack of preparation from our side that keeps us from being successful. One of the biggest sections in my list is how to learn more about the subjects which will able me to add just a little bit to my regular work paycheck and how can I use the industry I understand the "best" (computers) for making me more money. Being "rich" can be comprehend also as being smarter or becoming a better person, It's all depends on the list you're making. Keep this list updated, this is the hard trick you'll have to master; This will able you to monitor your progression and find new dreams. I have an uncle that good planing and a lot of self confidence got him the job of the president of a universal company and a lot of wealth for his good investments. He was never sorry for demanding more, and this is a lesson I will not forget. The bottom line is, be the best you can be, just be smart about it as we're not living alone and I DO think that being a good person is much more important than being successful, I just say you CAN be BOTH.


I would finish with happy new (Hebrew) year to all of you, may you get a little closer to fulfilling your dreams.
SHANA TOVA !

   

Posted by Oren Ellenbogen 
07/10/2005 10:55, Israel time UTC-07:00,     Comments [2]  | 
# Wednesday, September 21, 2005

Remember my last post on this subject ?
Just to refresh your memory, I've come across a strange Visual Studio .NET (2003) + Visual Source Safe (6.0d) problem:
I got "The operation could not be completed" alert every time I've closed my solution. Man, It was frustrating, but I think I have a solution for it if you're using the same versioning mechanism I'm using and that is - "Link File" between your Class Libraries. It seems that the "Link File" option mess the solution\VSS\projects up for some unknown and undebuggalbe(is that a word? no ah..., well, it is now) reason.

The solution is quite simple, remove the linked file and put it in each of your class libraries. I know, I hate this solution too, but at least it will keep the sanity of your solution which is much more important than "1 place"(except asp.net 1.1 project, which don't support "Like File" option) version holder.

Now I'm "The operation could not be completed" FREE !

.NET | VSS
   

Posted by Oren Ellenbogen 
21/09/2005 02:39, Israel time UTC-07:00,     Comments [2]  | 
# Sunday, September 18, 2005

I'm not a happy coder right now.
I gave Eran, a new gifted programmer in my department, a task:

I have a simple table in my database, named Users, with the fields ID (int, identity) and Name(varchar).
I want to send xml to a web-service which looks like this:
<User>
    <ID>1</ID>
    <Name>Oren</Name>
</User>

I want the web-service to add this row to the Users table in some magic way. I thought that by using Typed DataSet, which will use the table's schema, and loading the xml into it will do the trick, but I was wrong. We tried many things but they didn't seem to work.

The reason I want to use schema is to verify the given data(xml) structure before I insert it to the DB (and of course, without it how the DS(DataSet) will "know" to load it properly?). In addition, if tomorrow I need to add Password field to Users table, the only thing I'll have to do is to re-generate the Typed DataSet and set the password via the xml (<Password>mypassword</Password>).

The code looks like this:

string sXml = "<User><Id>1</Id><Name>Oren</Name></User>";
using (SqlDataAdapter adapter = new SqlDataAdapter("", connString))
{
    UsersDS ds = new UsersDS();

    System.IO.StringReader xmlSR = new System.IO.StringReader(sXml);

    ds.ReadXml(xmlSR, XmlReadMode.ReadSchema);
    ds.ReadXmlSchema(HttpContext.Current.Server.MapPath (".") + "\\UsersDS.xsd");

    adapter.Update(ds.Tables["Users"]);
}

For some reason my ds isn't getting filled.

Do you have any idea what am I doing wrong ?

btw - I know I can always parse the xml by myself and create the required commands, but I thought it will be a maintenance nightmare and less comfortable than letting the schema & the Typed DataSet doing the job for me.

Update [20.09.2005]:

Amir Markowitz, again, came to the rescue and with his help we've managed to solve this one:

using (SqlDataAdapter adapter = new SqlDataAdapter("SELECT * FROM Users", connString))
{
   SqlCommandBuilder scb = new SqlCommandBuilder (adapter) ;
   UsersDS ds = new UsersDS();
                    
   XmlTextReader reader = new XmlTextReader(new StringReader(sXml));

   ds.ReadXml(reader);
   ds.ReadXmlSchema(HttpContext.Current.Server.MapPath (".") + "\\UsersDS.xsd");

   adapter.Update(ds.Tables["Users"]);
}

Now, the xml data (in "sXml" variable) looks like this:

<UsersDS xmlns="http://tempuri.org/UsersDS.xsd">
    <Users>
        <UserName>Orenn</UserName>
        <Name>Oren E.</Name>
    </Users>
</UsersDS>

So thanks again Markowitz, I owe you one (again, add it to my list).

   

Posted by Oren Ellenbogen 
18/09/2005 07:06, Israel time UTC-07:00,     Comments [0]  | 
# Saturday, September 17, 2005

I'm responsible for an hybrid ASP-ASP.NET application with an ASP log-in screen; This screen authenticate the user and set a unique session value in case he's valid. All the other ASP screens check this unique session value and let the user stay in the system as long as it exists. The problem was that there were ASP.NET pages that I had to use this security mechanism in them, meaning to check the session in my .aspx files in the same pattern (same unique session) as the other .asp pages did. In order to do that I had to access the ASP session from my ASP.NET pages, which is impossible due to the simple fact that they DO NOT share the same "room" (teenagers problems, you know). The solution came after googling a little bit and testing the suggested solution on my application.

The pattern goes like this:

aspToaspnet.gif

Once again, I'm a happy camper.

   

Posted by Oren Ellenbogen 
17/09/2005 02:53, Israel time UTC-07:00,     Comments [0]  | 
# Tuesday, September 13, 2005

I've encounter a numerous bad usages of try, catch and throw statements in my last 3 years in .NET so I thought to write here my "best practices" in this subject.

Before I begin, just to remind you about the "using" keyword

" The using statement defines a scope at the end of which an object will be disposed. " (MSDN)

Meaning, this code:

using (MyDisposableObject o = new MyDisposableObject())
{
   // use o...
}

Is equal to:

MyDisposableObject o;
try
{
   o = new MyDisposableObject();
   // use o...
}
finally
{
   // Don't forget, MyDisposableObject must implement IDisposable
   o.Dispose();
}

The using statement is much more "cleaner" than the try-finally(->call Dispose) block. Of course, in order to use the using statement, MyDisposableObject must implement IDisposable interface, but most of the .NET frameworks' classes which use external resources do, so no problem here.

When do I use the using keyword instead of "try-catch(-finally)" ?

In any case your code block doesn't required any exception handling (catch) and you're using a disposable object.
 
When do I catch an exception ?
 
You should use the catch statement only if you can REALLY handle the exception - meaning you want\need to "eat"(catch it and do nothing about it) the exception or you (want to)\can try to "fix" the application's flow according the exception type (call transactionInstance.Rollback() in my data-access-layer if an error occurred, for example).
 
Do NOT catch exceptions as a "default" behavior in your code !
The following code is a BAD practice in exception handling:

try
{
   //some code
}
catch(Exception e)
{
   throw new Exception("X operation error: " + e.Message);
}
finally // if exists.
{
   //some code
}

Why is it bad ? The catch statement doesn't handling the original exception, it creates a (bad)new one which means:
  1. The Stack Trace of the original exception will be LOST, which means I lose the ability to view the entire "process" (who called to who flow).
  2. In the demonstrated code, I catch an exception and re-throwing a pointless new exception. Throwing exceptions is an expensive task so you should avoid (at any cost) throwing them as long as you don't really need to !
  3. If you wrap an exception, at least save the original exception in the InnerException property (I'll elaborate later on).
When do I wrap an exception, when do I rethrow it ?
  1. You should catch and wrap the exception with a new one only if you can add INFORMATIVE data to the original exception which WILL be used later on. Writing this type of code (in my DAL) will be a smart idea usually:

    SqlTransaction trans;
    SqlConnection conn = null;
    try
    {
        // use the connection to do some DB operation
        
        trans.Commit();
    }
    catch(Exception e)
    {
        if (trans != null)
            trans.Rollback();
        
        // Wrap the exception with DALException
        // I can check if e is SqlException and by the e.Number -
        // Set a "clean"(show to user) message to the DALException.
        // I can add the full "sql" exception in some custom property, 
        // I can determine which stored procedure went wrong, 
        // I can determine the line number (and so on).

        throw new DALException("clean message to the user", e);
    }
    finally
    {
        if ( conn != null && conn.State == ConnectionState.Open )
            conn.Close();
    }

    Why is this code smart ? Because I call the Rollback() in case of an error, which will ensure "clean" database. Because it "hides" the original SqlException which allows me, at my Business Layer, to catch a generic DALException which will abstract the Business Layer from the Data Access Layer. Because I CAN add more informative data to the exception so the Business Layer could send the GUI (to show the user).

  2. You should rethrow the exception if you catch-ed it but you "found out" that you can't really handle it:
    try
    {
        // do some code...
    }
    catch(Exception e)
    {
        if (e is SqlException)
        {
            // Add more information about the exception and
            // throw a new, more informative, exception:
            throw new DALException ("more data", e);
        }
        else
        {
            // I can't handle it really, so I'm not even going to try
            throw; // <-- look at this syntax ! I'll explain later on
        }    
    }
     
    Calling throw; will bubble the original exception (including its' Stack Trace) - this will actually "cancel" the catch statement.
When you wrap an exception, you should *almost* always use the "InnerException" property
 
When you wrap an exception, you should save the original exception as InnerException:

try
{
}
catch(Exception e)
{
   throw new MyCustomException("custom data", e);

   // OR

   MyCustomException mce = new MyCustomException("custom data");
   mce.InnerException = e;
}

This will preserve the original stack which will be important for later debugging.

 

Any Insights you want to share with me ?

   

Posted by Oren Ellenbogen 
13/09/2005 11:16, Israel time UTC-07:00,     Comments [2]  | 
# Sunday, September 11, 2005

Searching Oren Ellenbogen in Google placed me on the third(3rd!) place !
It's a huge progress if you keep in mind that just last week I was at the 15th place (second page, at the middle)...

update [14.09.2005]:

I'm at the first place now ! Respect !

   

Posted by Oren Ellenbogen 
11/09/2005 12:36, Israel time UTC-07:00,     Comments [1]  | 
# Saturday, September 10, 2005

Man, I had a lot on my mind during the previous week.
The week began with installing my application in one of our client's server which was pretty hard task due to couple of unexpected incompatibilities - lack of local IIS(meaning - no debugger!) and AD(Active Directory) complicated tree structure. This two alone are a major headache for any programmer, but I'm glad that it's behind me now (another happy customer, I LOVE IT!). The week continued and I had to fix some nasty bugs in a couple of applications which I'm responsible for, which turns out nice - there is nothing better than a good bug and a good solution (IMHO anyway).

I spent the end of the week to prepare for my presentation on the next week. I'm going to talk about DHTML, XML and XMLHTTP with my co-worker Roee(which is going to talk about Javascript and the server-side .vs. client-side pros & cons) in one of IDF computers' unit. It's a huge time consuming task to organize a decent power-point presentation, a few demos and a set of exercises and most importantly - organize my time properly. But again, I can't complain because I love giving presentation and work a little on my speaking abilities and time organization abilities.

In addition, I'm working now on Localization and Member-Roles Management solutions for our new ASP.NET 1.1 application. I know those requirements have built-in solutions in ASP.NET 2.0, but the client demanded ASP.NET 1.1 so unfortunately I can't use them yet.

btw - I'll upload the presentations, demos and exercises about XML\DHTML\XMLHTTP at the end of next week, maybe it will save one of you some time.

OK, back to work...

   

Posted by Oren Ellenbogen 
10/09/2005 04:38, Israel time UTC-07:00,     Comments [2]  | 
# Sunday, September 04, 2005

Hey y'all,

I can't seem to stop, those add-ins bastards are too addictive !
Oh well, here are more great VS.NET add-ins you should all check them out:

  1. GhostDoc - This great utility will able you to "auto" document your methods\properties with a single mouse click.
  2. WhidbeyCommands 2 - Just read the man's post :) TIP: if you give presentations while using the VS.NET, you MUST download this baby (check out "Demo font" option) !
  3. HandleWhiteSpace - Clean your files from unnecessary white spaces.
peace.
   

Posted by Oren Ellenbogen 
04/09/2005 09:08, Israel time UTC-07:00,     Comments [5]  | 
# Saturday, September 03, 2005

Sometimes we have to close the window after our screen logic has executed, so usually we're writing window.close(); in our page BUT this causes this message to arise -

close_areyousure.gif

If you want to avoid this message, simply write:

window.opener = window;
window.close();

   

Posted by Oren Ellenbogen 
03/09/2005 11:29, Israel time UTC-07:00,     Comments [1]  | 

It's possible to use built in keywords in order to mark some lines in you code for later reference. For example, I use the "TODO" keyword as a remark over a set of lines I know I'll have to change later on -

todos.gif

As you can see, my TODO task is now appearing at my Visual Studio .Net "Task list" which is great for a constant reminder.
As default, the Task list shows only the "Build Errors" so in order to support other keywords you'll have to (mouse)right-click over one of the table headers ("Description" for example) -> Show Tasks -> All (or any other suitable option). In addition, you can select how to sort the results by (I use "Priority").

* If you want to change the custom tasks priority or names - go into Tools-> Options... -> Environment -> Task List.

   

Posted by Oren Ellenbogen 
03/09/2005 11:13, Israel time UTC-07:00,     Comments [0]  | 
# Tuesday, August 23, 2005

It stroke me today at the train (on my way home) while I was reading a book named "Object Thinking" (by David West); I'm at chapter 7 which is talking about discovering the client domain, i.e what does he(the client) expect from the application. In short, although it's hard(especially if you're a technical person in your nature), you must understand the client's requirements without casting it to your world "I'll implement it with web-service" or "This is a classic multi-threading application"; You're job in this initiatory step is just to analyze the client's needs and trying to depict his world in simple "objects" world; What are my primary entities (for example: "Employee", "Employer", "Agreement" etc), what are the relationships between them and how the client expect to "activate" those entities (screens functionality).

I remembered my meeting with our last client and reading this stuff made me think about how well (?) did I managed to handle this task. While the client was depicting his world to me I was trying to understand and write his requirements and his special needs from the application. I've noticed that writing down the client's needs\remarks\requests sometimes stopped the conversation flow, caused needless repetition over the question & answers and sometimes even got me out of focus.

So, maybe tape-recording the entire meeting(well, the important stuff anyhow), concentrating on asking the right question and analyzing the answers later can create a better characterization ? better understanding of the client's domain ? shorter and more thorough meetings ?
It seems like a good idea, I think I'll give it a try on my next meeting.

What do you think?

   

Posted by Oren Ellenbogen 
23/08/2005 08:58, Israel time UTC-07:00,     Comments [2]  | 
# Sunday, August 21, 2005

Did I mention that I'm working with a well known hacker ?
Well, It's about time, so I present to you - Amir Markowitz aka "The Hacker".

Amir taught me today how to send javascript commands directly through the address bar !
Look at the "damage" he did to my site !

redbackground1.gif

As you can see, he managed to change the background color in one simple command.

Think about changing Page_IsValid property or performing __doPostBack("","") through the address bar -

javascript:void(Page_IsValid=true); __doPostBack("","");

This could be deadly if you don't perform Server-side validation as well !

 

 

   

Posted by Oren Ellenbogen 
21/08/2005 12:35, Israel time UTC-07:00,     Comments [0]  | 
# Saturday, August 20, 2005

Read this post by the legendary Brad Abrams and watch the videos you're interested at. I've seen "Designing Inheritance Hierarchies" and "Enabling Development Tools" videos (for the moment) and I promise that you can learn a thing or two as well ;-).

Happy learning...

update:
I thought it will be interesting to write my notes from the Designing Inheritance Hierarchies video, so here it is:

  1. Interfaces don't allow backward compatibility ! Let's assume we have to following interface

          public interface IMyInterface
          {
               void MyMethod();
          }

    Now let's assume that I have MyClass which inherits from IMyInterface. If I'll decide to add a new 
    signature to the interface, MyClass will be broken (TypeLoadException will be thrown in compile time).

  2. Base Classes version better than interfaces - if MyClass was inherited from MyBaseClass instead of IMyInterface I wouldn't have a problem to add new signatures to the class without causing the inherited classes to break.
  3. If you must inherit from 2 "root" classes, the recommended pattern is:

          public class A {}
          public class B {}
        
          public class C : A // Let's assume that A is "more" root to C than B
          {
             public B BInstance
             {
                get
                {
                    // return B class instance.
                }
             }
          }

  4. You can use Interfaces in "private" way via Explicit declaration:

      public interface IMyInterface
      {
         string ReturnSomething();
      }

      public class MyClass : IMyInterface
      {
          string IMyInterface.ReturnSomething()
          {
            return "oren";
          }
      }

      Now, when you create a new instance of MyClass, you won't see 
          ReturnSomething method on the public view:

      MyClass.gif

      Though, you can always call this method simply by casting c to IMyInterface:

      MyClassViaCasting.gif

      This can be useful if you want to "hide" some of the interfaces' abilities in your 
          class. This is recommendable if you don't want the "clients" to use a 
          certain behavior directly
through the class. 
         .NET framework use this ability in Int32 structure:

      int i = 5;
      i.ToString() // work
      i.ToInt32(); // don't work.
      ((IConvertible)i).ToInt32(); // work !

      " This member supports the .NET Framework infrastructure and 
        is not intended to be used directly from your code. " 
      (from MSDN, Int32.IConvertible.ToInt32 method)

 

I hope I've managed to give you some insights, just enough to convince you to start viewing these videos.

   

Posted by Oren Ellenbogen 
20/08/2005 06:21, Israel time UTC-07:00,     Comments [0]  | 

I'm currently using a .resx file at my projects to contain my friendly client's messages. I'm reading from this file via ResourceManager class which allows me to supply consistent messages at my GUI layer, e.g for every successful delete in my application you'll get the same message format "The {0} was deleted successfully" - in my "Workers" form you'll see The worker was deleted successfully and in my "Cars" form you'll see The car was deleted successfully;

I've encounter the SR (String Resource) Generator a week ago and I thought to give it a try. So, what is SR generator ?

" This custom tool allows the generation of a resource class (and optionally .resx file) from either a .resx file, or the Microsoft SR.strings file. "

I think that a simple example will show the tool's capabilities.

  1. I've downloaded the source which also includes the .msi file and installed it.
  2. I've added a file named SR.strings to my web application:

             SRGSolutionOnAdd.gif

  3. I've used the "Custom Tool" option and call SRCodeGen - this is an EXE which will parse your .strings file.
             SRGFileProperties.gif
     
  4. Next I've edit the SR.strings file -       

      [strings]
      Worker = Worker
      ItemDeleted(string itemName) = The {0} was deleted successfully.
      ItemAdded(int itemId, string itemName) = The {1} was added successfully, it's new ID is: {0}.

      [strings.he]
      Worker = עובד
      ItemDeleted(string itemName) = ה{0} נמחק בהצלחה.
      ItemAdded(int itemId, string itemName) = ה{1} נוסף בהצלחה, מספרו החדש {0}.

  5. I've saved the file in UTF-8 format, for Hebrew support.
             SRGFileEncoding.gif
     
  6. Rebuild the web project, this will cause the SRCodeGen to generate required files:
  7.                   SRGGeneratedFiles.gif
  8. Now lets use the SR class which was generated for us, here is my usage of it 
  9.          PageMessage.Text = SR.ItemDeleted(SR.Worker); // In my Worker.Delete()
     
             OR
             
             PageMessage.Text = SR.ItemAdded(newId, SR.Worker); // In my Worker.Add()
     
  10. Finally we can select the SR.Culture we want to use, so the messages will be formated in the correct language. This can be done easily be calling:
                  SR.Culture = new System.Globalization.CultureInfo("he");
   
                  OR
 
                  SR.Culture = new System.Globalization.CultureInfo("en");

         You can put this code in your Global.asax.cs in Application_Start method or 
         change it at any time, according to your needs.

 

This tool is a MUST in my opinion for two main reasons:

  1. IntelliSense, IntelliSense, IntelliSense ! (don't you love it ?!?!).
  2. Changing the messages Culture requires only one line of code, simple as that.
   

Posted by Oren Ellenbogen 
20/08/2005 01:10, Israel time UTC-07:00,     Comments [0]  |