In the world wide web, a good security policy starts with preventing people to access sensitive information. Someone looking for information will definitely look at the web site structure through the navigation elements, the menu and the sitemap. To prevent users to get this information, you can hide elements of your navigation controls by adding roles to the sitemap file and by adding a single attribute to your web.config.
First, implement in your web site a form authetication with roles and memberships. For more information on how to do that, I highly recommend Scott Guthrie's blog on Roles, Membership and Authentication for ASP.NET.
Second, implement the site map provider in your web.config file.
Third, add a sitemap file to your web project. In the file, add nodes that maps to your pages.
Fourth, add a MasterPage, and to it, add a menu control with a sitemapdatasource object. Bind the sitemapdatasource to the site map provider in your web.config file.
Fifth, add a treeview control in one page and a sitemapdatasource object. Bind the sitemapdatasource to the site map provider in your web.config file.
Check if everything compiles and that each control are shown appropriately.
Now, in the SiteMap provider in the web.config file, add the securityTrimmingEnabled attribute and set it to true.
In your sitemap file, add the role attribute and set its value to one of your roles you have defined.
Refresh your browser. If you have authenticated with a role not specified in the sitemap, or your are an anonymous user, the nodes with role values will not show for the SiteMap control and the Menu control as well.
Code Samples :
SiteMap Providers in the Web.Config file:
<siteMap defaultProvider="TopMenuSiteMapProvider" enabled="true">
<providers>
<!-- GENERAL ACCESS TO WEB SITE -->
<add siteMapFile="~/TopMenu.sitemap"
name="TopMenuSiteMapProvider"
type="System.Web.XmlSiteMapProvider"/>
<!-- LEFT MENU WITH SECURITY -->
<add siteMapFile="~/LeftMenu.sitemap"
name="LeftMenuSiteMapProvider"
securityTrimmingEnabled="true"
type="System.Web.XmlSiteMapProvider"/>
</providers>
</siteMap>
Site Map File with role attribute:
<siteMapNode title="$Resources:Menu, Administration.Title"
description="$Resources:Menu, Administration.Description"
roles="Administrateur" >
A Menu Control bound to a SiteMapDataSource object in the masterpage file:
<asp:SiteMapDataSource ID="SiteMapDataSource1" runat="server"
ShowStartingNode="false"
SiteMapProvider="LeftMenuSiteMapProvider" />
<asp:Menu ID="Menu1"
runat="server"
Orientation="Vertical"
DataSourceID="SiteMapDataSource1" />
Treeview control bound to a SiteMapDataSource object in a page
<asp:SiteMapDataSource ID="SiteMapDataSource1"
runat="server"
ShowStartingNode="true"
SiteMapProvider="LeftMenuSiteMapProvider" />
<asp:TreeView ID="TreeView1"
runat="server"
DataSourceID="SiteMapDataSource1"></asp:TreeView>
Let's have a look at what you are going to see of your menu control in your browser:
| Before signing in |
After signing in |
|
|
And what about the sitemap control:
| Before signing in |
After signing in |
|
|
Preventing people from seeing your web site archithecture is something you want to. And as we have seen it, it implies not code behind coding, only a few configuration here and there. When the Membership and roles are define, configuring the sitemap provider is a matter of a few seconds.
Best Regards!
Patrice
Last weekend I worked on an assignment which consisted on determining how to read, write and delete files in a specific folder and to read, insert, update and delete records in an MS Access 2003 database in a Medium Trust Level on a shared hosting context. The client mislead the assignment by confusing the Trust Level set at Medium with his capabilities to accomplish the tasks.
First, the Trust is useful to isolate different applications in a shared hosting environment and to enhance the security by prohibiting web application to access the host system resources. A web server administrator would want to prevent a malicious web applications to access files or directories of other web applications such like the web.config file to read, say, the connection string to get access to confidential data. On the other hand, the web server administrator would want to prevent a good intended or not web application to access the hosting machine resources like the registry, the file system or event logs.
There are 6 different levels of trust you may use for different purposes:
- Full : the default configuration in a development environment
- High
- Medium : the usual setting for a production environment
- Low
- Minimal
- Custom* : you may define your own security policy
* This trust does not exist but may be defined and customized accordingly to your needs.
The trust is define in the web.config file of the Framework 2.0.50727.
<location allowOverride="true">
<system.web>
<securityPolicy>
<trustLevel name="Full" policyFile="internal"/>
<trustLevel name="High" policyFile="web_hightrust.config"/>
<trustLevel name="Medium" policyFile="web_mediumtrust.config"/>
<trustLevel name="Low" policyFile="web_lowtrust.config"/>
<trustLevel name="Minimal" policyFile="web_minimaltrust.config"/>
</securityPolicy>
<trust level="Full" originUrl=""/>
</system.web>
</location>
There are several remarks to be done here. First, the security policy may be overridden because the property allowOverride is set to true. Also, the trust is set to Full. To override the security policy, the web.config file of the web application must be modified as follow:
<system.web>
<trust level="Medium" originUrl=""/>
Inside the <system.web> node, add a trust element. Set its level to one of the level available.
The trust levels are defined in a config file in the %WINDIR%\Microsoft.NET\Framework\v2.0.50727\CONFIG directory. The full trust level is a special case where the ASP.NET host does not apply any security and is therefore considered as having full trust on the local machine zone. It is mapped to an internal handler. The other trust levels are defined in files. The file has two main sections. The first define the security classes and the second the permission related to it.
To understand what is a Medium Trust Level, it is good to compare the web_mediumtrust.config file with the web_hightrust.config file. When comparing the two files, we remark the medium one has much less IPermission elements define. Also, some IPermission are much more restrictive. For instance, the medium FileIOPermission has read, write, append and PathDirectory only while the high FileIOPermission has unrestrictive permission.
You can write your own custom security file.
First, copy the %WINDIR%\Microsoft.NET\Framework\v2.0.50727\CONFIG\web_mediumtrust.config and rename it to something like web_customtrust.config.
Second, open the new file and add, remove, modify the file to meet your needs. To add a new security, add a SecurityClass and add a IPermission.
Third, open the web.config file of the %WINDIR%\Microsoft.NET\Framework\v2.0.50727\CONFIG\ directory. Add your custom policy.
<trustLevel name="Custom" policyFile="web_CustomTrust.config" />
Set the allowOverride to true.
Fourth, open the web.config file of your web application.
Fifth, inside the system.web node, add a trust node and set its trust level to Custom.
<system.web>
<trust level="Custom" originUrl=""/>
Another way to reference the custom trust file, is to add the web_CustomTrust.config file at the root of the web application. Then, in the web.config file, add the following nodes :
<location allowOverride="true">
<system.web>
<securityPolicy>
<trustLevel name="Custom" policyFile="web_CustomTrust.config" />
</securityPolicy>
<trust level="Custom" originUrl="" />
</system.web>
</location>
For more information on trust levels, I suggest you to read these articles:
From the MSDN Site (How To: Use Code Access Security in ASP.NET 2.0) this table is quite informative:
| Trust Level |
Key Capabilities and Restrictions |
| Full |
No restrictions imposed by code access security. |
| High |
No unmanaged code.
No enterprise services.
Can access Microsoft SQL Server and other OLE DB data sources.
Can send e-mail by using SMTP servers.
Very limited reflection permissions. No ability to invoke code by using reflection.
A broad set of other framework features are available. Applications have full access to the file system and to sockets. |
| Medium |
Permissions are limited to what the application can access within the directory structure of the application.
No file access is permitted outside of the application's virtual directory hierarchy.
Can access SQL Server.
Can send e-mail by using SMTP servers.
Limited rights to certain common environment variables.
No reflection permissions whatsoever.
No sockets permission.
To access Web resources, you must explicitly add endpoint URLs—either in the originUrl attribute of the <trust> element or inside the policy file. |
| Low |
Intended to model the concept of a read-only application with no network connectivity.
Read only access for file I/O within the application's virtual directory structure. |
| Minimal |
Execute only.
No ability to change the IPrincipal on a thread or on the HttpContext. |
Also, have a look at Table 4: Default ASP.NET Policy Permissions and Trust Levels on the same web page which will explain you what permissions are available at what level.
An exception may be raised if the defined trust level does not allow your action. It may look something like this:
Request for the permission of type 'System.Security.Permissions.FileIOPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' failed. mscorlib
This exception was raised because the FileIOPermission did not authorised the performed action.
Finally, the assignment I spoke of earlier was more about configuring a folder to give Modify permission (read, write, delete) and giving away a few piece of code on how to connect to a MS Access database to read, update, insert and delete records and on how to read, write and delete files a folder.
Best regards,
Patrice
I worked this week on a Console application that would allow me to resize all images in a folder to thumbnail size of 128 by 128 pixels. This small project was meant to correct a problem on a web site. My friend can upload any kind of images (bmp, jpg, gif, png) of any size to her web site. The images are then displayed in a catalogue. There are up to 20 images per page. For consistency, every image are set to be displayed in a 128x128 pixels. When the user click on the image, it is displayed in it original size in another browser:
<a href='http://www.website.com/Uploads/Catalogue/myImage001.jpg'
target="_blank" id="lnkImage">
<img id="imgItem" title="My Image"
src="../Uploads/Catalogue/myImage001.jpg"
style="height:128px;width:128px;border-width:0px;" />
</a>
The problem with this html is if the image is large, it will take time to download. On the other hand, if the image is small, the user does not get anything better when clicking on the image to look at it in another browser because it is of the same size.
To correct this, I suggested her to always upload image files in their original size, the larger the better. And I would take care of displaying images on the right size.
So I develop a class that I would add to the business logic layer of her web site and also to a console application which would run once to resize all of her images already uploaded on her web server.
Here is the class I creates;
2: ''' Resize images to 128x128px
4: ''' <param name="sourceFilename">
5: ''' Complete input file name</param>
6: ''' <param name="targetFilename">
7: ''' Complete output file name
9: ''' <remarks></remarks>
10: Public Shared Sub ResizeImageBad( _
11: ByVal sourceFilename As String, _
12: ByVal targetFilename As String)
14: Dim img As System.Drawing.Image = Nothing
15: Dim graph As Graphics = Nothing
16: Dim smallImg As System.Drawing.Image
17: Dim rectangle As Rectangle
18: Dim smlSize As Size = New Size(128, 128)
21: img = System.Drawing.Image.FromFile(_
23: smallImg = New Bitmap(_
27: rectangle = New Rectangle(_
33: graph = Graphics.FromImage(smallImg)
34: graph.CompositingQuality = CompositingQuality.HighQuality
35: graph.SmoothingMode = SmoothingMode.HighQuality
36: graph.InterpolationMode = InterpolationMode.Bicubic
37: graph.DrawImage(img, rectangle)
39: smallImg.Save(targetFilename)
41: Catch ex As Exception
42: cLogEventViewer.LogError( _
43: System.Reflection.MethodBase.
GetCurrentMethod.DeclaringType.Name & _
44: " - Exception Resize Image - " & _
48: If Not img Is Nothing Then
53: If Not graph Is Nothing Then
When I ran the console application targeting a folder containing only jpg, gif or jpg files, the console application throw exceptions for gif files. The png files were not resized and fortunately the jpg were ok.
Here is the log error from the event viewer:
"A Graphics object cannot be created from an image that has an indexed pixel format. "

After a few readings, I found out that the problem was at the pixel format level. In the code sample I provided earlier, I used the pixel format provided by the System.Drawing.Image object instance loaded from the file name as you can see on line 26.
I changed the pixel format to System.Drawing.Image.PixelFormat.Format24bppRgb which provides 24 bits per pixel, 8 bits for Red, 8 for Green and and 8 for Blue. This change stopped the errors. The GIF files were resized and their weight were lighter. Unfortunately, when I tried to view the image applications I used sent an error on opening.
I search a little further and I added another filter on the file,
graph.PixelOffsetMode = PixelOffsetMode.HighQuality
that I inserted between line 34 and 35. Also, I looked for the ".gif" extension at the end of the file name. If the file name ended with ".gif", I then specified that specific format:
smallImg.Save(targetFilename, Imaging.ImageFormat.Gif)
Also, I changed the InterpolationMode to HighQualityByCubic which provides a higher quality after resizing the GIF file.
Let's have a look at the images. On the next image, on the left, is the original GIF image and on the right is the resized GIF image.
As you can see, the image on the right, after resizing has lost some quality.
Well... I have looked for quite some time now on how I could solve the quality issue and I must admit it, I am now clueless. To complete the application, however, I decided to reformat the GIF to JPEG. doing this solves completely the quality issue but does not answer how I could resize GIF images.
If someone has an answer, I am curious to know how you did it.
But for now, here is the method I use to resize images:
1: ''' <summary>
2: ''' Resize images to 128x128px
3: ''' </summary>
4: ''' <param name="sourceFilename">Complete input file name</param>
5: ''' <param name="targetFilename">Complete output file name</param>
6: ''' <remarks></remarks>
7: Public Shared Sub ResizeImage( _
ByVal sourceFilename As String, _
ByVal targetFilename As String)
8:
9: Dim img As System.Drawing.Image = Nothing
10: Dim graph As Graphics = Nothing
11: Dim smallImg As System.Drawing.Image
12: Dim rectangle As Rectangle
13: Dim smlSize As Size = New Size(128, 128)
14:
15: Try
16: img = System.Drawing.Image.FromFile(sourceFilename)
17: smallImg = New Bitmap(smlSize.Width, smlSize.Height, PixelFormat.Format24bppRgb)
18: rectangle = New Rectangle(0, 0, smlSize.Width, smlSize.Height)
19:
20: graph = Graphics.FromImage(smallImg)
21: graph.CompositingQuality = CompositingQuality.HighQuality
22: graph.SmoothingMode = SmoothingMode.HighQuality
23: graph.PixelOffsetMode = PixelOffsetMode.HighQuality
24: graph.InterpolationMode = InterpolationMode.HighQualityBicubic
25: graph.DrawImage(img, rectangle)
26:
27:
28: If targetFilename.LastIndexOf(".gif") > 0 AndAlso targetFilename.EndsWith(".gif") Then
29: targetFilename = targetFilename.Replace(".gif", ".jpg")
30: smallImg.Save(targetFilename)
31: Else
32: smallImg.Save(targetFilename)
33: End If
34:
35: Catch ex As Exception
36: cLogEventViewer.LogError( _
37: System.Reflection.MethodBase.GetCurrentMethod.DeclaringType.Name & _
38: " - Exception Resize Image - " & _
39: ex.Message & " " & _
40: ex.StackTrace)
41: Finally 'Clean up!
42: If Not img Is Nothing Then
43: img.Dispose()
44: img = Nothing
45: End If
46:
47: If Not graph Is Nothing Then
48: graph.Dispose()
49: graph = Nothing
50: End If
51: smlSize = Nothing
52: rectangle = Nothing
53: End Try
54: End Sub
Have a good one!
Cheers!
Patrice
Why should I use Nullables? What are they for? Why have they added the Nullables to the .Net Framework 2.0?
These are questions I asked myself. And because you are good people, I will share my thoughts with you. Isn't it wonderful? Nah! I'm just kidding. In fact, the following post is the product of some readings on the topic and I started using it in my day-to-day coding because it answered a real issue.
First thing first. Let's consider the following scenario: a form on a web page somehow bound to a database. On the form, there are several kind of inputs: textboxes, dropdownlists, radiobuttons, checkboxes, textboxes for date/time and so on. What if some fields are not mandatory? It means these fields may be left empty. How should you treat an empty field considering that the database accepts null values?
How do you manage the situation? Because, philosophically speaking, an absence of value is a value. It means the user did not want to add his input, for any reason, on the form.
With value types however, how could you move that piece of information from the form to the database knowing value types cannot be null (C#).
A Value type cannot be null because its value is not a pointer to an address in memory but the value itself. Whereas the reference type is a pointer to an address in memory. A null value represents an address in memory, x00000000. So setting a reference type to null is in fact pointing to an address in memory. When times come to instantiate the object, the pointer is redirected to the address in memory where the object is (somewhere on the heap).
There have been some thoughts spent over this to overcome the impossibility of assigning a null value to value types. Some have thought about adding a bite to all value types where this extra bit would serve as a flag to indicate whether or not the value is null. Although this possibility seems sexy, it seems it would have been a nightmare to manage and moreover to validate the flag whenever accessing its value. For instance, what if a Byte could have an extra bite to flag its has a null value. By definition, a Byte is defined with 256 possibilities ranging from 0 to 255 (00 to FF). An extra bite would mean 257 possibilities (there is the nightmare).
Another way to represent the null value is to use a default values throughout the application. The problem with this approach is to select a value that will be never use.
A third way is to wrap the value type in a reference type, such like the Object class or a custom class. Although it seems practical, it is however costly on memory and performance.
With the coming of the .NET Framework 2.0 and the Generics, the Framework addresses this issue with the Nullable<T> type. This type is a Generic class with a type value constraint. Since only type values can not be null, it makes sense.
Let's see how we can use the Nullable<t> Type:
1: public static void ShowNullable()
2:{
3: //Nullable<T> aInt = null;
4: Nullable<int> aInt = null;
5:
6: try
7: {
8: int assignerInt = aInt.Value;
9: }
10: catch (InvalidOperationException ex)
11: {
12: Console.WriteLine("Exception of type
InvalidOperationException: {0}", ex.Message);
13: }
14: catch (Exception ex)
15: {
16: Console.WriteLine("Exception de type
System.Exception: {0}", ex.Message);
17: }
18:
19: //Using the HasValue property
20: if (aInt.HasValue)
21: Console.WriteLine("Value: {0}", aInt);
22: else
23: Console.WriteLine("Value: null");
24:
25: //Using GetValueOrDefault
26: Console.WriteLine("Default value (with a parameter):
{0}", aInt.GetValueOrDefault(-5));
27: Console.WriteLine("Default value (without a parameter):
{0}", aInt.GetValueOrDefault());
28:}
On line 4), we see how a Nullable can be declared. Like Generics, the Nullable is fully qualified with a type parameter specified between angle brackets. The initial value of aInt is null. When you try to retrieve a Nullable value having a null value, it throws an InvalidOperatorException. To prevent the exception from being thrown, it is best to test the Nullable with the HasValue property. The property returns false when it has null as a value. You can process the value according to it. Another feature of the Nullable is the GetValueOrDefault where it returns a default value when the Nullable is null. You have the choice to assign yourself the default value to be returned in case the Nullable is null, or you let the Framework return the default value (0, false, date.MinVale, and so on).
For C# users, there are two things worth mentioning. First is the shortcut for declaring a Nullable. The other is the shorcut for the GetValueOrDefault method. Let's have a look at the following code sample:
1: public static void ShowNullableOperators()
2: {
3: Nullable<int> a = 1;
4: int? b = null;
5: int? c = null;
6: c = a ?? 3;
7: Console.WriteLine("Value of a: {0};
Value of b: {1},
Value of c with operator ??: {2}", a, b, c);
8: a = null;
9: c = a ?? 3;
10: Console.WriteLine("Value of a: {0};
Value of b: {1},
Value of c with operator ??: {2}", a, b, c);
11: }
On line 3), it is the usual Nullable declaration. On the next line, it is the shortcut for declaring a nullable. In this example, I have declare a Nullable of type int. I also assigned a null value to it. On the sixth line, it is the default value comparator. This operator first evaluate the left argument, in this case a, to determine if it has a null value. If it is not a null value, it returns the value. Otherwise, it returns the right value.
Conclusion
The Nullable type is a convenient type to use when a real type may be assigned to a null value. The few properties available are significant and useful. The HasValue property gives the opportunity to the programmer to decide the logic to be applied in the case of a null value. If no logic is required, the GetValueOrDefault method is a good alternative.
This post concludes the topics I covered four weeks ago in a lunch meeting. As you can see, there was a lot of stuff but it was a good study that covered some of the most important new features in .NET Framework 2.0.
Cheers!
Patrice
Sorry for taking so long to write the last part. I got a busy week last week with a few parties, a girlfriend birthday, an interview with a potential client bewise - which I will come over in a near future - and so on.
The last post was on three fundamental considerations of the Generics: Generic constraints, generics types and methods and generic type inference. When I review the second part, I believe I went over the type constraints a little too quickly and I consider I should have spent more time discussing and implementing examples to demonstrate how to efficiently use these. I took notice of it and I should come back to it when time will allow me to do so.
Today, we shall discuss of two things. How the JIT compiler manages the Generics and the Generic classes available in the .NET Framework.
JIT Compiler
The main task of the Just In Time - JIT - Compiler is to translate the IL, the Intermediate Language, to the native language in order to be executed by the computer.
The JIT Compiler produce different code for each type value but shares some native code regarding the generics for the reference types. It can do this because the compiler knows the length in memory of each reference, which is 32 or 64 bits depending on the architecture of the machine. An array of references will always be of the same size in the memory, whatever it is in the array, because the reference of the array is a pointer placed on the stack. Items in the array are however place on the heap and thus, dynamically created whenever needed and using the required memory they have to.
There are performance issues when using arraylist that are annihilated when using Generics. For instance, when someone used an arraylist of Bytes in .NET 1.1, each item had to be boxed and then to get a hold on the reference of the boxed value. When using a Generic List<T> there is no boxing/unboxing effect. Also, each item of the list is, for instance, a Byte instead of an Object. The array is of the right type and in memory is the right size.
This gives a better efficiency, saves memory, and is faster on runtime because there is no time lost on boxing or unboxing, there is no validation when unboxing and the Garbage Collector does not have to get involved when unboxed values are no more referenced.
Generic Classes
1. List<T>
The Generic List<T> is the counterpart of the arraylist in the .NET 1.1. There are a few functionalities and caracteristics that existed in arraylist that were not implemented in the Generic List<T>. Among them, the Missing in Action methods are:
- Adaper
- Clone
- FixedSized
- Repeat
- SetRange
- Synchronized
We can make an old API into a Generic List by implementing the IList and IList<T> interfaces.
The new functionalities are:
1. ConverAll: Converts each item of one type to another type and returns a list of the later.
2. Exists: Checks if at least one element in the list meets the predicate.
3. TrueForAll: Check if every element in the list meets the predicate
4. FindFirts, FindLast, FindAll: Find an element in the list.
5. RemoveAll: Remove all elements in the list that meets the predicate
6. ForEach: It is not the ForEach iterative structure but this method allowes to perform an action on each item of the list.
2. Dictionary<TKey, TValue>
The Generic Dictionary<,> is the counterpart of the HashTable in the .NET 1.1. Because in the .NET 2.0 the HashTable implements the IEqualityComparer interface, some functionalities available with the Dictionary<,> are also available with the HashTable. However, the most meaningful difference between the two is their behaviour when retrieving a value associated to a key.
If we ask for a value with a key not present in the dictionary, the HashTable will return a null value. The dictionary<,> will throw a KeyNotFoundException.
Both supports ContainKeys which retrieve the value associated to the key, if present, place it in the output parameter and returns true. Otherwise, it returns false and place the default value in the output parameter.
3. Queue<T>, Stack<T>
Both are lists that do not allow random access to their elements. Accessing items at random offers poor performances. However, when retrieving elements in the proper order, these list are quite effective.
Queue<T> is a FIFO, First In First Out list. To add an item, we have to use the Enqueue method. When adding an object to a queue, the object is added at the end of the list. To retrieve an item, we have to use the Dequeue method and the first object in the list is removed from the list.
To get the next object in the queue or the stack without removing it from the list, we can use the Peek method.
Speaking of the stack, it is a FILO, First In Last Out (or a LIFO, Last In First Out depending on how you see your half filled (or is it empty) glass of water)) list. To add an item, we use the Push method which adds an item at the beginning of the list. To get (and remove) an item from the list, we use the Pop method. It retrieves the last object put in the list.
4. SortedList<TKey, TValue>, SortedDictionary<TKey, TValue>
The sortedList allows access to its elements through an index. The sortedDictionary, however, is through a key. The most significant carateristic of both generic classes is that when enumerating items, they are sorted by their key.
Another thing worth mentioning is when using the sortedlist, that list is more memory efficient in contrast to the sortedDictionary. The sortedDictionary is more faster when adding unsorted items. However, when items are sorted, the sortedlist is more faster than the sortedDictionary.
5. LinkedList<T>
This is a new list in .NET 2.0. What is it exactly? It is a chained list where each item is a node linked to previous node and linked to the next node. This list is quite efficient when you need to iterate from the beginning to the end or from the end to the beginning. However, random access is not efficient and is rather slow.
Conclusion
This was the third post out of three on Generics. In this third part of the sequel, we examined how the JIT Compiler worked when faced with Generic and where were the advantages of using the Generics. We also summarized the Generic classes available in the .NET Framework. We saw that each class had its own advantages and taking advantage of it is merely a question of which context is the most favourable.
We could write until tomorrow morning about the Generics. However, there is only one thing you must have in mind though. And it is the fact that they are quite more effective and convenient to use than their counterpart (arraylist or hashtable).
Mots clés Technorati :
.NET,
.NET 2.0,
Generics
In the previous post, I covered different aspects of the .NET Framework, namely, the situation at the time of the .NET 1.1 and the challenges it offered to both the programmers and the compiler. I also named a few needs the .NET Framework 2.0 had to meet in order to correct the grievances expressed when using .NET 1.1. The solution offered, as we saw, was the Generic namespace. We quickly check the benefits someone gets from using the Generics and I finally reviewed a few vocabulary so we could discuss the Generics on the same basis.
In this post, I will talk about the different Generics a programmer can use, the type constraints and type inference.
Generics
There are two kinds of Generics. There is the Generic type and the Generic Method.
4 Generic Types
The Generic type is composed of 4 elements: classes, interfaces, delegates and structures.
A Generic class is declared as followed:
Let's consider the following class:
When instantiating the class and calling the method ShowMyRealSelf, we get the following results:
Using a generic class:

Results:

How does it work when you try using interface? Consider the following interface and class implementations :
and the instantiation of the class is as follow:
will produce this result:

The last sample is quite simple (save for the French class names...). The class MyGenericClass implements a custom interface ITransformation. These two expect a type as an input and will produce another type as an output. This is shown by how the method Transform uses the type parameters. In this example, I transform some juice to wine. With the same class, I could transform milk to butter or yogurt or cheese (or with divine help, water to wine - no offence meant).
Generic Method
A generic class usually has generic methods. A generic method may return a generic type. it can also have generic type arguments. It must however define at least one type parameter. Here is the signature of the ConvertAll method from the generic class List.
List<TOutput> ConvertAll<TOutput>(Converter<TInput, TOutput> conv).
The ConvertAll method is quite useful for converting a list of one type to a list of another type. For example, someone could use this method to convert a list of candidates to a list of employees. Of course, this conversion implies somehow some logic to be applied to each item of the list to be converted. But first, let's have a look at the method ConvertAll.
Its return type is a List of TOutput. The TOuput type will be defined by the parameter type <TOutput>.
It expects to get as an argument a Converter type variable, which is a generic delegate with two type parameters. The first type parameter is the input type. The second, defined by the type parameter of the ConvertAll method, is the output type.
Using the previous example of candidates and employees, lets suggests we do have two classes: a Candidate class and an Employee Class. Thus, the generic delegate should be declared as follow:
The logic to convert a Candidate to an Employee should be a usual method like this one:
Finally, the overall class of hiring a bunch of candidates:

Type Constraints
Type constraints on generics are useful when someone wants to control how his generic will be used.
There are 4 type constraints:
- Reference type constraint: a generic method or a generic type with a reference constraints means the type parameter must be a reference type (an instance of Employee for example).
- Value type constraint: the parameter type can only accept value types (int, bool, enum, ect).
- Constructor constraint: the type parameter must have a parameterless constructor.
- Derivation constraint: it means the type parameter must be or derived from the specified class.
The way a constraint must be declared is as follow:
In the previous example, the generic method has a constructor constraint. It means an object of type T may be instantiated somewhere in the code. Since the type value may not be instantiated, a value type such like int, or bool is not allowed.
Constraints can be combined for a more secure use of the generic. As you might expect it, the type value can only be used alone.
Type inference
Type inference demonstrates the power of the compiler. It shows how much the compiler is "intelligent" enough to infer the type parameter based on the type argument.
Type parameter inference:

Usually, when using a generic method, specifying the type parameter is the standard. However, type inference allows the programmer to be a bit lazy and to omit the type parameter.
Both ways are good programming practice. However, specifying type parameter is, in my own opinion, a better practice for the sake of code readability.
Conclusion
With this second part of three blogs on Generics, we have looked at the two different kind of generics someone may encounter, generic type and generic method. In the section relative to generic method, we reviewed how to use the ConvertAll method from the generic List class. Also, we reviewed the 4 constraints which allows the programmer to limit the way his generics may be used. Finally we examined the type inference and how it could simplify code writing and how it takes its token on readability.
The last post will look at how the JIT manages memory with generics. Also, we will look at the 4 generic classes available.
Don't miss the last one!
Patrice
Mots clés Technorati :
.NET,
Framework 2.0,
Generics
The Generic namespace is a new feature of the .NET Framework 2.0 and it is, in my own opinion, the most important innovation the Framework 2.0 has to offer.
Overview of the situation from the .NET 1.1
Before the .NET Framework 2.0, programmers had to work with the ArrayList object in order to create arrays. The problem programmers experienced was the casting (or boxing) involved when using ArrayList. Adding instances of any object to an array involved, somewhere, a cast to an Object. When the time came to retrieve them, the programmer got an Object type and had to cast the Object to the right type. The last cast could lead to a runtime bug since the programmer had no way to know what type was in the ArrayList unless the code is properly documented. Also the compiler could not check the programmer's code. It had to trust the programmer for the right casting. Otherwise a bug could be generated at runtime.
Basic needs and requirements for the .NET 2.0
The needs and requirements the .NET Framework 2.0 had to meet were to cut down the number of casting (or unboxing) involved, allow a better validation at compile time, increase the Intellisense capabilities, decrease the number of bug at runtime due to bad castings and finally to enhance the readability of the code.
The .NET Framework answered these challenges with the Generic namespace.
Advantages of using Generics
When you start using the Generic, you get the following advantages compare to ArrayList. You get an implicit documentation of the code since the programmer knows the type of the objects in the array. The compiler knows what to expect and, therefore can perform validation at compile time. These checks increase the code robustness and decrease the possibilities of encountering a bug at runtime due to a bad casting. The reduction of the number of casting (and boxing) involved at runtime involve an augmentation of performances and a better memory management. When using Generics, the programmers reduce his code manipulation hence he increases his productivity.
Vocabulary
Before we get our hand dirty, let's check out a few terms commonly used with Generics.
Boxing means to take a Value Type (int, bool, enum) and wrap it into an instance of a reference type of an object (ie. from a integer to an object).
Unboxing means to unwrap the object and downcast it to a Value Type.
Casting means to convert a reference type to another reference type.
Implicit cast means there is a casting without using an conversion operator.
Explicit cast means a casting using a conversion operator.
Parameter type is what appears between angle brackets (<T>).
Argument type is the real type used with generics.
Unbound Generic type is a generic declaration without Argument Types.
Opened Constructed Type is a generic with argument types where the argument types are defined from somewhere else (like a generic class with generic methods).
Closed Constructed Type is a generic with argument types where the argument types are known.
Conclusion
This concludes the first part of the Generics where we saw why the Generics are so welcomed with the .NET Framework 2.0. We also had a look at a few vocabulary terms which are commonly used when you get started working with Generics.
The second part should look at the different generics someone may work with, the constraint types and type inference. This next part will also involve some code samples to get a better idea of the concept involved.
See you soon,
Patrice
Last Friday was my first presentation on a topic of my choice. The idea of such talks on lunch time to team members is from Laurent Duveau. These talks are good on developing skills for speaking in front of a crowd and to learn something on a topic relative to .NET.
The topic I chose is large. I decided to talk about Generics and Nullables. My experience with .NET Framework is somewhat short (definitely not as good as I would have liked). I already have worked with Generics for three years (since VS 2005 Beta) but never enough to talk about it with a new cutting edge so other team members could benefit from it. I used a pedagogic approach to prepare my presentation: an introduction to both subjects (What were the needs), a development body (classes, methods, advantages) and a conclusion (advantages and limitations).
The challenge for me for this first presentation was to talk about a topic on which I had a thin knowledge. In front of colleagues who are more knowledgeable on .NET Framework, the last thing I had in mind was to make a fool of myself or to talk only of general matter. That was for me a matter of self-esteem.
So I invested a lot of time on getting my presentation ready. "C# in Depth" and MSDN were my primary references. I also read a few blogs for complementary information. But the topic was deep. I should have let the Nullables for another talk. Next time I will talk about a technical topic, I will be more careful on selecting my subject. Thus, I could cut down my preparation time with less thing to cover, simpler demo to set up and fewer Powerpoint slides to get ready.
The presentation went well. The team members (Bruno, Vincent and Louis-Philippe) actively participated to the talk by asking questions, having conversations on the current topics or by asking an example or requesting a demo. I was proud of my preparation because the conversation leaded by Louis-Philippe went over a few things I was about to talk about.
This presentation gave me the opportunity to learn a few new things that I am now applying in my day to day developing tasks. Particularly, I use the Nullable type because the web application I am working on is laying on a database. Regarding the Generics, I learnt how to use the ConvertAll<T> method to convert a list of one type to a list of another type and I apply this method wherever I can. Also, I taught to a colleague how to use the Nullable and the ConverAll method and she is now using this new knowledge in her web application building.
All in all, the experience I got on presenting a technical topic was incredible: I build up a powerpoint slideshow, a demo to show a few code samples and the content preparation. I also got benefits from the presentation by having a deeper understanding of the .NET Framework and this understanding will be a good kick start for my next Microsoft Certifcation, the MCTS 70-536. There is no doubt in my mind that with this presentation my study on Generics and Nullable for the MCTS 70-536 certification is completed.
In this way, I must conclude that my first presentation was a complete success.
There are many ways to create a web site. However, there are two templates that are commonly used around the world. One is to use a single navigation tool such as a menu. Another one is to use two menus - a top menu beneath the web site banner and a left (or right depending on your tastes) menu.
The first time I used a sitemap, I struggled a few hours to get it right. The problem was me. I did not understand the workings on sitemap providers.
Using a custom sitemap filename
My first mistake, that day, was to use a custom sitemap file name, like MyWeb.sitemap instead of web.sitemap. When I added the SiteMapDataSource with default settings to my MasterPage, nothing worked properly.
Let's consider the following layout in a MasterPage:

As you can see on the screenshot, I added a sitemap file named MyWeb.sitemap. Here is the content
When I do a View in Browser of with the default configurations in the web.config file, I get an error from IIS:

This means the SiteMap provider is expecting a sitemap file named web.sitemap.
So, if you rename the MyWeb.sitemap file to web.sitemap and then view in browser, you are in your right to expect to see something different from the previous screen. Actually, the page is shown and IIS did not throw the previous error:
What is the trick? Or, more down to earth, how does it work?
Opening the web.config file will not get you any information. In fact, the web.config file has nothing relating to anything close to a sitemap reference. To find your answers, you need to open another web.config file located in the following directory:
%WINDIR%\Microsoft.NET\Framework\v2.0.50727\CONFIG\web.config
** WARNING: Unless you know what you are doing, if I were you I would not change anything in this file...
Excerpt of the web.config file:

The SiteMapDataSource first reads in the web.config file inside the solution to find its provider. Finding none, IIS redirects the SiteMapDatSource to the web.config file of the framework on which the web site is running.
While we have the %WINDIR%\Microsoft.NET\Framework\v2.0.50727\CONFIG\web.config file opened, we will copy the sitemap node into web.config file from the current web site project. The code must go inside the system.web node. A view in browser demonstrates the default web page is still showing correctly.
To be able to rename the web.sitemap file to something else, we need to change a few things in the new sitemap providers section from the current web.config.
First, you need to change the siteMapFile attribute. This is where you specify to IIS your sitemap file name. Let's change it for TopMenuWeb.sitemap. A quick glance in IE to see if the change has been taking into effect. It does. But what we get is another error:
This error means you have at least two site map providers having the same name.
After providing another name to the site map provider into our web.config file name, TopMenuWebSiteMapProvider for instance, we can see the results in IE. Everything works fine because we did not change the sitemap file yet. Doing so, IIS will throw a third error:

This error is caused by the SiteMapDataSource control in the masterpage. Earlier, we changed the sitemap provider in the web.config file. We also renamed the site map file. But all the while, the SiteMapDataSource control was always expecting the web.sitemap file. Since it can not find it anymore, IIS throws the above error.
The solution is to provide to the SiteMapDataSource control the site map provider name that will be bound to the TopMenuWeb.sitemap xml. In the SiteMapDataSource, you add the SiteMapProvider property and fill it with the sitemap provider name that is mapped to the existing sitemap file in the project, currently the TopMenuWebSiteMapProvider.
A refresh of IE shows the expected results.
Adding another sitemap
Adding as many sitemap files as desired is child play. The trick is to add as many sitemap providers in the web.config file.

And one more menu control bound to another siteMapDataSource control in the master page:

And finally, the leftMenuWeb.SiteMap file content:
Before going to the browser, I added some style to the MasterPage for the sake of seeing the skeleton of the web site. It is pretty ugly, please be kind and don't throw me any shoe...
Mainly, what is different from the previous browser results is that I changed an attribute in both SiteMapDataSource. I changed the ShowStartingNode value from true to false. This way, the menu shows not the root element but the first child level.
I hope this will quickly get you started when you start designing your new web site layout.
Best regards,
Patrice
Recently, I worked on a small home project. This project objective was to manage of a condominium. Since the condominium holds a few numbers of co-owners and the data access weight would be small, I chose to build a database with Microsoft Access 2007. After inserting some data into the database, I soon realized I had to build a web site which would stand on the database for data persistency because sooner or later, I would like to manage, in a decentralized manner, the condominium and where I would do a minimum of support. Letting people with an Access database is not the best choice and developing Access forms is not what I consider a funny hobby. However, what I consider funny, though, is to build a web site and watch it live.
So, I decided to build a web site with an Access database. To make the process even funnier, I also decided to use the GridView and the AccessDataSource controls. The objectives were to maximize my productivity, minimized the code writing and build something simple quickly. The GridView control is a great tool for data presentation in a tabular layout. It also allows to quickly visualize or edit data. The choice is ideal for expenses, revenues, suppliers and contracts data presentation.
Specifications
I chose to work with VS 2008 SP1, .NET 3.5 SP1, Microsoft Access 2007. The language I selected is C#.
Adding a database
After starting a new project in C#, I added my Microsoft Access 2007 database into the App_Data folder. I want to specify the AccessDataSource control does not work with a secured database with a username and a password because you can not specify a ConnectionString. The work around is to use a SqlDataSource control.
Here is the schema of the Access database used in the first part of this blog entry:
Design et Databinding
After adding the database, I dragged and dropped on the Default.aspx form, from the toolbox, a GridView control and an AccessDataSource control.
A new fonctionality of VS 2008 is to work with the designer and the ASP.NET code in the same window:
Let’s configure the AccessDataSource control with the designer.
When choosing the Demo.ACCDB database in the App_Data folder, we get an error from the designer. It seems the designer cannot get the database schema:
Since the database as a .ACCDB extension, you need to save the database into another format: .MDB. After renaming the database, there is no other action to undergo. The database is fully recognized as you can see in the Server Explorer window. You are ready to work with it.
We can now configure the connection to the database with the AccessDataSource designer. To complete the design and databinding section, you need to associate the GridView DataSourceId property with the AccessDataSource ID property.
Data presentation
The data presentation in a GridView using an AccessDataSource control is a child play. All you need to do is to create a SelectCommand inside the AccessDataSource control:
When assigning the DataSourceId of the GridView with the AccessDataSource ID property using the designer, the wizard adds for you every column identified in the SelectCommand.
What is left is to delete the OwnerID, which is the primary key in the Owners Table and to add the DataKeyNames property to the GridView. The property is useful to identify the fields inside the grid that are primary keys:
If we had many primary keys, we would have assigned the DataKeyNames like this:
A quick save and followed with a View in Browser show the selected data in the grid:
Excerpt of the GridView configuration:
Browser results :
Of course, the layout is entirely customizable through the CSS or through the designer. Also, webmasters of multi-language web sites may like the fact the headers can be regionalized. Finally, the data may be formatted:
Updating data
Updating data is one of the most important aspects in a data driven application and the GridView control is an ideal control that get the job done right. While developing the web site, this technical aspect offered me the most interesting challenges. The correctly configured AccessDataSource control allows to, without any code line, to update data:
Excerpt of the GridView control:
UpdateCommand from the AccessDataSource control:
Why does the update works without any code line? It works because the GridView control adds the parameter values to the parameter collection of the UpdateCommand. It first passes the parameter values from the BoundField objects and then it passes the values from the DataKeyNames property.
Adding a field in the collection of columns without adding it to the property definition of the UpdateCommand of the AccessDataSource controls breaks the order into which the fields are added to the collection. This action is responsible for breaking the UpdateCommand from working correctly and what you get is a GridView no more updating the data. We can conclude the order into which the parameter values are added to the collection is important to the UpdateCommand and it confirms the next statement from MSDN:
“… any parameterized SQL queries that you specify in the SelectCommand, UpdateCommand, InsertCommand, and DeleteCommand properties must match the order of any Parameter objects that are in the corresponding parameter collection. If no parameter collection is specified on the AccessDataSource, the order of parameters that are supplied to these operations must match the order in which they appear in the underlying SQL statement.” Ref: MSDN
Excerpt of the GridView configuration:
Excerpt of the AccessDataSource control:
And the fact that we specify the parameters collection inside the AccessDataSource control does not resolve the problem at hand :
Excerpt of the AccessDataSource control:
The solution to the problem is to add a property to the undesired boundfield to prevent the gridview to add it to the collection. adding the readonly property and setting it to true provides the solution:
excerpt of the accessdatasource control:
When you decide to use the templatefield, its presence does not have any impact on how the gridview control adds its parameters to the updatecommand. the accessdatasource still works perfectly:
excerpt of the gridview configuration:
Cascading DropDownLists
When we go to the edition mode, we open the door to bad data input from the users. We can limit the mistakes by using the dropDownLists whenever it is possible. In the following example, I will use three tables to show expenses data: the Expenses table, the Suppliers table and the Contracts table:
Here is the first declarative part of the GridView control :
And here is the columns that are included into the GridView control :
And finally the SelectCommand of the AccessDataSource :
The result in the browser:
That said, we want to edit all values from the above Grid. The database schema of the Expenses shows the Expenses table contains foreign keys pointing toward the Supplier table and the Contract table. Those foreign keys are systemic and meaningless to the users. How do we prevent input mistakes ?
All we have to do is to give to the user restricted meaningful values to choose from, link them to systemic values and bind them to the table. Let’s see how we do it…
Inside the columns collection, we first add a CommandField column the property ShowEditButton. This quickly add all necessary buttons to select and update data:
Let’s start with the suppliers. We replace the BoundField SupplierName by a TemplateField:
And we add another AccessDataSource to bind it to the dropDownList :
From this example, I need to clear out a few things. The AccessDataSource2 control is placed outside the GridView control, somewhere on the page. Also, as we can see, the SelectedValue property of the DropDownList uses the Bind function and receives as a parameter the field SupplierID. This field is provided by the AccessDataSource1 control, which is used to fill the grid. This means we need to add the field to the SelectCommand of the AccessDataSource1:
Here is the result:
We do the same process form the ContractNo column. We add a TemplateField, a dropDownList and a third AccessDataSource control:
Here is the excerpt of the TemplateField :
And the third AccessDataSource, dropped somewhere on the page, outside the GridView:
And the results are as follow:
The problem of data input of a contract number is half solved. We allow users to choose from a meaningful contract numbers lists. Some, however, are not related to the selected supplier though. We solve this problem by, first, moving the third AccessDataSource, AccessDataSource3, into theGridView, inside the contract TemplateField, right beneth the contract dropDownList:
Contract TemplateField Excerpt:
After that, we add a filter into the AccessDataSource control:
The filter is an expression alike a where clause in an Access query (in this case since we use AccessDataSource). The filter applies to explicitly specified fields and we add it a parameter value. The filter parameters are defined by a FilterParameters collection. Each filter is associated to a control inside the GridView and to one of its property that contains the value to be retrieved in order to apply the filter. In our case, the filter expression is applied on the field SupplierID with the help of the selected value of the suppliers DropDownList.
Finally, before proceeding to results, we have to remove the property SelectedValue from the contract dropDownList. If not, an exception is raised:
However, when showing the page in the browser, we get another exception:
We need to add to the update parameters collection in order to specify the parameters :
When we view the page in the web browser and we test the update capabilities of the grid, we quickly realize that something is wrong. The data seems to disappear from the grid and a quick glance at the data in the database confirms it:
Before the updates :
After 3 updates :

It seems the GridView can no more make the association between some controls and the UpdateCommand from the AccessDataSource. We also take notice that the SupplierID column accepts the new values selected by the suppliers dropDownList but the selected values associated to the contracts dropDownList are discarded.
To correct this, you need to associate the lost value to the UpdateCommand from :
First, the aspx page, by associating the OnRowUpdating command to a function name used in the code behind:
And then, the code behind:
Now, let’s see the results:
Inserting data through the GridView
The gridView is not the tool to use for inserting data into a database. If you are using an AccessDataSource control, it is highly recommended to use a FormView control or a DetailsView control.
However there is a way to make it happen and it is to use the FooterRow. For more information, please read the following: how to use FooterRow to insert data. As I mentioned, beware, this is not something I recommend. I rather mention it as a way some have explored.
Conclusion
Finally, the gridView is a great tool for all purpose applications where you need a tabular layout for your data and apply your own CSS. Associated to a data source, such like the AccessDataSource, your productivity will no doubt increased. Correctly configured, the AccessDataSource requires the minimum of code line.
Although everything looks simple, the architecture of such application using a data souce like the AccessDataSource control is quite simple and rarely meets the n-tier architecture layers we often see in most serious business applications.
Before I wrote the condominium management web application, I never used AccessDataSource or SqlDataSource. I rather liked to write my own layers: a data access layer and a business layer. But I must confess, the AccessDataSource offers all the tools a developer requires to build a home web application.
Patrice
Mots clés Technorati :
GridView,
AccessDataSource
Two weeks ago was the DevTeach event held in Montreal. The conference received more than 300 attendees and over sixty speakers. There were more than 230 sessions given in three days including special events. The topics covered were vast and diversified ranging from Agile, Web Development, .NET, Silverlight, Ajax, SQL and Architecture. For me it was the second time I attended a DevTeach Conference. The first time I was there as a Universal Thread reporter. The second time I was there as a simple attendee. Both experiences were great but the second time offered me the opportunity to enjoy it every second.
I attended many sessions on Silverlight. When no Silverligth session caught my attention, I gave in to other sessions where their topic touched as many aspects of .NET as possible. Of course, my choice scope remained within my professional interests. For the DevTeach review, I will present my Top 3 best sessions I attended.
Top 3 – Position #1 : Laurent Duveau –
The session of Laurent Duveau represented exactly what I was expecting form the DevTeach Conference regarding SilverLight 2.0. What I mean is someone taking a concise topic and drilling it down to its core. And this is exactly what did Laurent Duveau. He targeted a topic, Building a business application SilverLight, and showed how to build a simple data driven Silverlight application. For all details on his presentation, please follow the link.
Top 3 – Position #2 : Beth Massi –
Beth Massi (Beth Massi's blog) is a VB expert… humm the best expression would be she is the Queen of VB, but this is only my opinion. I went to her session because friends of mine, used to DevTeach, warmly and highly recommanded it. Her session was on LINQ and XML with Office 2007. Two things hit me to the point I was at a certain point speechless, if not breathless. The first thing was to see how easy it was to write XML literals with embedded expressions (Lets see the VB 9.0 neat new features). The other thing is to edit Office 2007 documents (Word – docx, Excel – xlsx, PowerPoint – pptx). For more information on how she did it, please read Beth Massi’s blog and download her solution.
Top 3 – Position #3 : Jim Duffy –
Jim Duffy’s session (Jim Duffy's blog) was the last session on the last day and it was a sweet conclusion to the 2008 edition of DevTeach. I really like Jim Duffy. He was funny, expressive, and a good teacher. Regarding his session, it was flawless because it showed an aspect of ASP.NET development and it examined it thoroughly . Jim Duffy showed how to implement Microsoft Visual Earth into ASP.NET application. To get a good idea on how to do this, please look the video on the next link. His source code of his demo can be downloaded here. But make it hurry, the link may disappear anytime soon. Also, open the next link to download all necessary API to build Live applications: dev.live.com.
Finally, DevTeach 2008 was a great event. What best describes DevTeach is the speakers and the many topics covered in a wild variety of ways. This year, although the subscription cost more than $1200 CAN the attendees received close to a $1000 in softwares : Visual Studio 2008 Pro, Expression Web 2.0 and the TechEd 2008 DVD set.
Hope to see you there next year!
Patrice
Last November 6 and 7, I went to the TechDays 2008, a sponsored conference by Microsoft held on two days at the Palais des Congrès de Montréal. A month after the event, I would like to talk about two sessions I attended that particularly held my attention.
The conference was an opportunity for me to have a first contact with the Silverlight technology. A week before the event, I started reading Scott Guthrie’s blog (http://weblogs.asp.net/scottgu/) on how to get started with Silverlight, but for many bad reasons (I know don’t tell me) I did not persevere.

I attended Zheng XiQing (http://blogs.msdn.com/canux/ and http://blogs.msdn.com/canux/archive/2007/03/01/microsoft-canada-s-first-user-experience-advisor-qixing-zheng.aspx ) and Laurent Duveau (http://weblogs.asp.net/lduveau/ ) sessions on Silverlight. Zheng XiQing is a First User Experience Developer Advisor. Her session showed the limitless possibilities that Silverlight has to offer at the presentation layer and the customization and personalization of the GUI. I saw with her that the sky is the limit with Silverlight. Well, to get there, you will need a good share of creativity and a deep understanding of Microsoft Expression Blend.
The other session that caught my attention was the two part sessions given by Laurent Duveau. Laurent has demonstrated that with a few Silverlight controls and the use of Blend someone can get running a Silverlight application with video feeds. The lesson I got from watching Laurent is that Silverlight is not as complicated as I first understood it. The trick is to work with Blend. Laurent also showed another tool that is worth mentioning: Deep Zoom composer. I highly recommend it because the tool renders large images in small tiles. And when you zoom in, you get another set of tiles that represents the size of your screen. For a demo on how the tool is used, please follow the link: http://memorabilia.hardrock.com. Please have a close look on the stamp on the envelope addressed to Sgt Buddy Bresner.
Finally, the event was well organized and the attendees were so well taken care of by Microsoft.
Patrice
Welcome .NET community to this new blog!
As a welcome word, I will present your new blogger and try to limit the different horizons this blog will cover here.
Let’s start with the blogger. My name is Patrice Paré and I live in vicinity of Montreal, Canada. I consider myself an intermediate level web developer with three years of experience with the .NET technologies. I have been working for RunAtServer Consulting Inc. for the last 6 months. In October, I got the MCPD Web Application certification.
As an intermediate developer, I intend this blog will address a public of junior experience in .NET technologies. My hopes are this blog will cast some light on .NET technologies and how to use it. Of course, any of you are welcome to read the blog and leave a comment.
Finally, when I speak of .NET technologies I think at ASP.NET, Ajax and Silverlight. In fact, we will look at the development of Rich Internet Application in a Windows context. The web development will be done using Visual Studio 2008 which means I will also talk about the .NET Framework 3.5 and 2.0. Of course, any self-respectful development is intended to be somehow useful which means it as to be deployed. My staging environment will be a Windows environment with IIS running the web apps.
I hope you will enjoy reading my posts
Best regards,
Patrice