Windows Vista Beta 2 (Build 5384.4) and 2007 Office System Beta 2 were released to MSDN Subscribers early this morning. [Been trying to blog about it for the whole day but couldn't fine the time.] I have already got the bits and installing them now on my primary machine.
I'm actually more interested in the WinFX Beta 2 that was also released today and I have managed to download all the bits except for the Windows SDK - it is taking ages to download. I was a bit disappointed that there were no newer updates to Windows Workflow Foundation. Looks like it is still stuck at Beta 2.2.
Well, enjoy all the new stuff!
Wednesday, May 24, 2006
Sunday, May 21, 2006
A.Lousy.Weekend
I've been feeling lousy all weekend due to flu and migraine. Caught the flu last Monday and up till now, I'm still down with it. I only took a day off and last Friday, after returning home from a drive under the hot sun, I started to have migraine. I felt the air was warm and stuffy. Did not manage to do anything on Friday night. Wanted to watch TV but then I'm already in a semi-conscious state. Decided to go to bed instead. I slept for 11 hours and heck, the migraine is still there.
For the whole of Saturday, my brain isn't functioning well. The medicine is also making me drowsy but yesterday it was the last dose. The doctor didn't give me any antibiotics this time and that's why the flu has been dragging. I tried to sleep but my brain keep visualizing the Visual Studio 2005 IDE ... "my Workflow code couldn't compile, my tracking service isn't working and my host application - how to code it?"
The migraine lasted for the whole day. I don't know what I was doing for the whole of Saturday. I don't think I can recall it in total right now. Even this morning, I woke up feeling lousy. My head was heavy and my body feels like it doesn't want to get out of bed. My throat was clogged and I started coughing.
Blast! I hope this gets over soon.
For the whole of Saturday, my brain isn't functioning well. The medicine is also making me drowsy but yesterday it was the last dose. The doctor didn't give me any antibiotics this time and that's why the flu has been dragging. I tried to sleep but my brain keep visualizing the Visual Studio 2005 IDE ... "my Workflow code couldn't compile, my tracking service isn't working and my host application - how to code it?"
The migraine lasted for the whole day. I don't know what I was doing for the whole of Saturday. I don't think I can recall it in total right now. Even this morning, I woke up feeling lousy. My head was heavy and my body feels like it doesn't want to get out of bed. My throat was clogged and I started coughing.
Blast! I hope this gets over soon.
Saturday, May 13, 2006
Garage.Sale
Woke up early in the morning today and felt like cleaning my room. Thanks to mom's "smart clean" tissues, I was able to clean the entire room without any nose irritation. Rearranged some of my books, relocated my routers and packed-up some CDs. I also found these:
1) Two pieces of Apacer 512MB PC2700 DDR 333 Notebook RAM
2) A brand new Microsoft Multimedia keyboard which I won from one of the MIND events last time.
Anyone interested to buy them?
[Edited: I put in the proper specs for the stuff]
1) Two pieces of Apacer 512MB PC2700 DDR 333 Notebook RAM
2) A brand new Microsoft Multimedia keyboard which I won from one of the MIND events last time.
Anyone interested to buy them?
[Edited: I put in the proper specs for the stuff]
Friday, May 12, 2006
Entity.Translation.Service
[Update] I have received numerous bashings on this post. Please take note that this post was posted long before there were any modern technologies to serialize entities accurately. It is ok if you don't agree with the method but it was just something I had to do for my scenario back then. With WCF today, there is no longer a need to do any of this.
Recently, I have encountered an issue that is by-design when using custom entity classes (or Business Entities) with Web Services. Being an advocate of custom entity classes, I have always believed in lightweight objects when it comes to ferrying data across service boundaries. However, little did I realised that when dealing with Web Services, it is not so straight-forward afterall.
Let's explore the problem.
Suppose we have a simple custom entity class like the following:
As you can see, the Customer entity is a pretty straight-forward class. Notice that it is marked as [Serializable] to enable it to serialize across boundaries. Also take note of the FullName readonly property which I purposely created to demonstrate the problem.
Next, let's look a Web Method in our ServiceProvider.
We are now ready to use our Web Service. We will start by creating a new project and use the Add Web Reference... option to reference our Web Service. We will name the Web Service reference as CustomerService.
Let's write our consuming method.
Cannot implicitly convert type 'ServiceProvider.Customer' to 'Business.Entities.Customer'
Replacing the code in line 5 with the following will conveniently solve the problem.
So what is wrong? Now, if you go to the definition of the ServiceProvider.Customer class, you will realized that it is not our Business.Entities.Customer class but a class generated for the proxy when we add the web reference (An imposter!). So what happened to our Customer class? The answer is that this is by-design because whatever types that we send across in a Web Service will be serialized into XML and we cannot control the consuming end (i.e. they may be running on different platforms).
After searching the web for nights and posting here, here and here, I have yet to find a satisfying answer. One of the links that were provided in the forums suggested to use CodeDom to generate the classes but I feel that it is an overkill solution.
So how do we solve it? Enter the Entity Translation Service. The idea of the Entity Translation Service is to convert our custom entity classes into XML string and pass them through the Web Services layer. On the consuming end that we have control, we will convert the string back to our custom entity classes. This way, we eliminate the need for generating proxy entity classes in our application while still staying true to the Web Services architecture.
Below is the code for the EntityTranslator. Feel free to use it but remember to give me some credit okie? :p
To use the EntityTranslator, modify the Web Service method.
To call our new Web Service method, we will modify the method on the consuming end.
Before concluding, I would like to mention that although the solution provided above may seem viable but certain considerations have to be taken when using such approach. In the example, we returned a Customer entity class but if we are passing in a Customer entity class to the Web Service method, proper type checking should be done because the string that is coming in could be anything.
So thats it! I hope you guys enjoyed the article ... uh! I mean post. :p
Recently, I have encountered an issue that is by-design when using custom entity classes (or Business Entities) with Web Services. Being an advocate of custom entity classes, I have always believed in lightweight objects when it comes to ferrying data across service boundaries. However, little did I realised that when dealing with Web Services, it is not so straight-forward afterall.
Let's explore the problem.
Suppose we have a simple custom entity class like the following:
1using System;
2using System.Collections.Generic;
3using System.Text;
4
5namespace Business.Entities
6{
7 /// <summary>
8 /// Represents a Customer.
9 /// </summary>
10 [Serializable]
11 public class Customer
12 {
13 private decimal customerId;
14 private string firstName;
15 private string lastName;
16
17 public decimal CustomerId
18 {
19 get { return customerId; }
20 set { customerId = value; }
21 }
22
23 public string FirstName
24 {
25 get { return firstName; }
26 set { firstName = value; }
27 }
28
29 public string LastName
30 {
31 get { return lastName; }
32 set { lastName = value; }
33 }
34
35 /// <summary>
36 /// Gets the fullname of the customer.
37 /// </summary>
38 public string FullName
39 {
40 get { return firstName + " " + lastName; }
41 }
42
43 public Customer()
44 {
45 }
46
47 }
48}
49As you can see, the Customer entity is a pretty straight-forward class. Notice that it is marked as [Serializable] to enable it to serialize across boundaries. Also take note of the FullName readonly property which I purposely created to demonstrate the problem.
Next, let's look a Web Method in our ServiceProvider.
1 [WebMethod]
2 public Customer GetCustomerWithoutTranslation(decimal customerId)
3 {
4 // Return a Customer object.
5 // NOTE: Should call a method from Business Component to retrieve customer.
6 Customer customer = new Customer();
7 customer.CustomerId = 8888;
8 customer.FirstName = "Serena";
9 customer.LastName = "Yeoh";
10
11 return customer;
12 }Once again, it is a typical Web Service method that returns an instance of our Customer entity class. [Notice that I did not use a Business Component in my example. In real-life applications, it is always a good practice to use a Business Component to return the custom entity.]We are now ready to use our Web Service. We will start by creating a new project and use the Add Web Reference... option to reference our Web Service. We will name the Web Service reference as CustomerService.
Let's write our consuming method.
1 protected void Button2_Click(object sender, EventArgs e)
2 {
3 // Call web service.
4 ServiceProvider.CustomerService svc = new ServiceProvider.CustomerService();
5 Customer customer = svc.GetCustomerWithoutTranslation(8888);
6 }Up to this point everything seems to make perfect sense but if you attempt to compile your code, you will be treated to the following error:Cannot implicitly convert type 'ServiceProvider.Customer' to 'Business.Entities.Customer'
Replacing the code in line 5 with the following will conveniently solve the problem.
5 ServiceProvider.Customer customer = svc.GetCustomerWithoutTranslation(8888);If you compile your application now, everything should be alright. However, if you inspect the ServiceProvider.Customer class, you will notice that something is missing - The FullName property is not available. [At this point, you may try to cast the class to Business.Entities.Customer but you will encounter the same error that was mentioned earlier.]So what is wrong? Now, if you go to the definition of the ServiceProvider.Customer class, you will realized that it is not our Business.Entities.Customer class but a class generated for the proxy when we add the web reference (An imposter!). So what happened to our Customer class? The answer is that this is by-design because whatever types that we send across in a Web Service will be serialized into XML and we cannot control the consuming end (i.e. they may be running on different platforms).
After searching the web for nights and posting here, here and here, I have yet to find a satisfying answer. One of the links that were provided in the forums suggested to use CodeDom to generate the classes but I feel that it is an overkill solution.
So how do we solve it? Enter the Entity Translation Service. The idea of the Entity Translation Service is to convert our custom entity classes into XML string and pass them through the Web Services layer. On the consuming end that we have control, we will convert the string back to our custom entity classes. This way, we eliminate the need for generating proxy entity classes in our application while still staying true to the Web Services architecture.
Below is the code for the EntityTranslator. Feel free to use it but remember to give me some credit okie? :p
1
2//===============================================================================
3// TITLE : Entity Translator
4// AUTHOR: Serena Yeoh
5// BLOG : http://serena-yeoh.blogspot.com
6//===============================================================================
7
8using System;
9using System.Collections.Generic;
10using System.Text;
11using System.Diagnostics;
12
13using System.IO;
14using System.Xml.Serialization;
15
16namespace TranslationService
17{
18 /// <summary>
19 /// Provides functions to translate custom entity classes.
20 /// </summary>
21 /// <typeparam name="TEntity">The type of the entity.</typeparam>
22 [Serializable]
23 public class EntityTranslator<TEntity>
24 {
25 public EntityTranslator()
26 {
27 }
28
29 /// <summary>
30 /// Converts an entity to XML string.
31 /// </summary>
32 /// <param name="entity">The entity object.</param>
33 /// <returns>An XML representation of the entity.</returns>
34 public string ToXML(TEntity entity)
35 {
36 string output = string.Empty;
37
38 using (StringWriter writer = new StringWriter())
39 {
40 XmlSerializer serializer = null;
41
42 // Serialize the entity.
43 serializer = new XmlSerializer(typeof(TEntity));
44 serializer.Serialize(writer, entity);
45
46 // Get serialized string.
47 output = writer.ToString();
48 writer.Close();
49 }
50
51 // Return the result.
52 return output;
53 }
54
55 /// <summary>
56 /// Converts a XML string to a custom entity.
57 /// </summary>
58 /// <param name="xmlString">The XML string representing the entity.</param>
59 /// <returns>An entity object.</returns>
60 public TEntity FromXML(string xmlString)
61 {
62 TEntity entity = default(TEntity);
63 XmlSerializer serializer = null;
64
65 using (StringReader reader = new StringReader(xmlString))
66 {
67 // Deserialize the entity.
68 serializer = new XmlSerializer(typeof(TEntity));
69 entity = (TEntity)serializer.Deserialize(reader);
70 }
71
72 return entity;
73 }
74
75 }
76}
77Basically, the EntityTranslator class accepts a Generic type and manages the serialization/deserialization with an XmlSerializer. As you can see, the code is pretty straight-forward. As long as the custom entity classes are marked with the Serializable attribute, the XmlSerializer will be able to handle them.To use the EntityTranslator, modify the Web Service method.
1 [WebMethod]
2 public string GetCustomer(decimal customerId)
3 {
4 // Return a Customer object.
5 // NOTE: Should call a method from Business Component to retrieve customer.
6 Customer customer = new Customer();
7 customer.CustomerId = 8888;
8 customer.FirstName = "Serena";
9 customer.LastName = "Yeoh";
10
11 // Create translator.
12 EntityTranslator<Customer> translator = new EntityTranslator<Customer>();
13
14 // Return the translated string.
15 return translator.ToXML(customer);
16 }Notice we are returning a string now instead of a Customer entity class.To call our new Web Service method, we will modify the method on the consuming end.
1 protected void Button1_Click(object sender, EventArgs e)
2 {
3 // Call web service.
4 ServiceProvider.CustomerService svc = new ServiceProvider.CustomerService();
5 string s = svc.GetCustomer(8888);
6
7 // Translate the string to custom entity.
8 EntityTranslator<Customer> translator = new EntityTranslator<Customer>();
9 Customer customer = translator.FromXML(s);
10
11 Response.Write(customer.FullName);
12 }Notice that we are able to get back our Customer class and access the FullName property now. There you go, problem solved!Before concluding, I would like to mention that although the solution provided above may seem viable but certain considerations have to be taken when using such approach. In the example, we returned a Customer entity class but if we are passing in a Customer entity class to the Web Service method, proper type checking should be done because the string that is coming in could be anything.
So thats it! I hope you guys enjoyed the article ... uh! I mean post. :p
Monday, May 08, 2006
Midnight.Installation
What am I doing staying up so late? Waiting for my installation to complete lor. So, sleepie liow. The blue bar still taking its own sweet time, one-block by one-block. *YawN* Fai-Di-lah!!! (Faster-lah) ... zzzZzZZZZZZZ
Friday, May 05, 2006
Ent.Lib.2.Hands.On.Labs
The hands-on-labs for Enterprise Library 2.0 is now available on MSDN. Download it to learn more about the new and revised features of Enterprise Library for .NET Framwork 2.0.
Monday, May 01, 2006
All.About.Computers
Got a phone call from Dell Support this morning. Whoa! Their technicians are working on Labour Day. They wanted me to run some test to see if other things are broken. Everything appears to be ok so far, except for the kick @$$ graphics card.
Honestly, I think the Dimension 5150 is a value buy - Pentium D processor, 17" Flat Panel, 1 GB RAM and 80GB HDD (I chipped in a DVD writer as well *Muahaha*). Feels like sitting in front of a server - watching the two CPU charts go up and down in Task Manager. There is only one thing that I don't like which is the keyboard - it has very thin borders and it looks very weird. Maybe, I will give my Logitech wireless keyboard to my mom.
Anyway, while scouting Sunway Pyramid's new Digital Centre last week I found this handsome HP dv1000 series notebook. The display unit was a dv1300 series model that comes with 100GB HDD and 1GB RAM. It is an awesome looking notebook with 14" WXGA widescreen which makes it slightly smaller than my darling X1000 (now with nx7000 mobo). The weight is lighter too. Price is ranged from RM4,999 to RM5,899 depending on specifications.
Yesterday, I wanted to show it to my friend who is looking for notebooks and I was shocked to find that even the display unit was sold out. With such a sleek looking notebook, who could resist? I was told that, that they are shipping in the higher-end models, dv1600 series, this week and they come with Core Duo processors. *drooling*
I was also told that it comes with a remote control but sadly, it doesn't support Media Centre Edition, otherwise, it would be more awesome. The speakers located at the front are pretty stylo. The only complain I have is that the graphics card is an integrated card which I don't fancy. Hopefully, the future models will come with more kick @$$ graphics card.
Since I have postponed my next notebook refresh cycle to 2008 (and not to mention I'm damn broke now), all I can do now is just talk about it. If you are scouting for a notebook, do check this handsome out. ;)
Honestly, I think the Dimension 5150 is a value buy - Pentium D processor, 17" Flat Panel, 1 GB RAM and 80GB HDD (I chipped in a DVD writer as well *Muahaha*). Feels like sitting in front of a server - watching the two CPU charts go up and down in Task Manager. There is only one thing that I don't like which is the keyboard - it has very thin borders and it looks very weird. Maybe, I will give my Logitech wireless keyboard to my mom.
Yesterday, I wanted to show it to my friend who is looking for notebooks and I was shocked to find that even the display unit was sold out. With such a sleek looking notebook, who could resist? I was told that, that they are shipping in the higher-end models, dv1600 series, this week and they come with Core Duo processors. *drooling*
I was also told that it comes with a remote control but sadly, it doesn't support Media Centre Edition, otherwise, it would be more awesome. The speakers located at the front are pretty stylo. The only complain I have is that the graphics card is an integrated card which I don't fancy. Hopefully, the future models will come with more kick @$$ graphics card.Since I have postponed my next notebook refresh cycle to 2008 (and not to mention I'm damn broke now), all I can do now is just talk about it. If you are scouting for a notebook, do check this handsome out. ;)
Subscribe to:
Posts (Atom)