Wednesday, March 21, 2012

EXPRESSION BLEND RESOURCES

What will you be doing in 5 days?

See the link here
See the link here
See the link here
See the link here

Thank you.

Tuesday, March 20, 2012

RIA Services: RAD for the Middle Tier

RIA Services is a new Microsoft framework for developing n-tier Line of Business (LoB) applications. RIA Services make it easier to build Silverlight applications that communicate with a server, which is the focus of this article. As a developer, RIA Services provides automatic code generation for common scenarios where you need to perform CRUD
operations on data and have a consistent model to validate data across tiers. The following sections explain how to get started with RIA Services, specify a data source and a UI, and automatically generate code for CRUD operations. Let me show you the big picture of RIA Services from an architectural perspective first.
Understanding RIA Services Architecture
RIA Services solves problems in n-tier application design for Silverlight applications by making it easier to serialize and stream objects across a network, sharing common validation among tiers, and automating asynchronous communication. To compare current development practices to what RIA Services offers, consider a common architecture, shown in Figure 1, using Web services to allow a Silverlight application to communicate with the server.

Figure 1. N-Tier architecture with Web services.
To the left of Figure 1 is a Silverlight control in a browser, which is the presentation tier. Following the network connection to the right, the Web service resides on the server, which is a separate tier where Business Logic Layer (BLL) and Data Access Layer (DAL) code reside; the sidebar, Layers and Tiers, explains the difference between layers and tiers.
LoB application development is very much about managing data properly. In the Web services scenario in Figure 1, you can see how data management must be handled in each tier. Perhaps you have a framework that makes it easier to stream data across the wire, but you still have manual work to do in each tier to manage CRUD operations.
Observe in Figure 1 the separate validation code in each tier of the application, because in many cases you can’t make the assumption that presentation tier validation is sufficient. Especially in a Web services scenario, any client can send bad data.
A common problem with network communications is timeouts and managing perceived performance in the presentation tier in the face of latency. A common way to handle this is via asynchronous calls where your thread returns to the UI immediately and the application later handles the return thread from the Web service and marshals the call back onto the UI thread to update the screen. There are patterns and framework support for managing this, but you must write the code yourself. The solid line between tiers demonstrates the fact that communication is synchronous by default.
"

“Up to now, developers have been fortunate to have the tools to build sophisticated n-tier architectures easier than earlier generations of software technology. However, this scenario becomes even easier with RIA Services.”
"
Up to now, developers have been fortunate to have the tools to build sophisticated n-tier architectures easier than earlier generations of software technology. However, this scenario becomes even easier with RIA Services. Figure 2 shows how RIA Services simplifies data management, validation, and communications.
Figure 2: RIA Services architecture.
The single Data Objects block in Figure 2 demonstrates that the UI and BLL/DAL tiers use the same objects. RIA Services supports LINQ to SQL, ADO.NET Entity Framework, and POCO out of the box, reducing the amount of work that you must do to move data across the network. Similarly, Validation has a single block, showing that the same validation rules defined in the BLL will be used in the UI. RIA Services build a proxy for the UI layer to encapsulate asynchronous communication, represented by the dashed line between UI and middle tier, freeing you from the extra coding.
The rest of this article shows you how RIA Services can help reduce the amount of code you write for n-tier LoB applications, starting with an explanation of how to start a Silverlight project that uses RIA Services.
Starting RIA Services in a Silverlight 4 Project
The easiest way to use RIA Services is via the Silverlight Application wizard in Visual Studio 2008. The following steps will walk you through the process of creating a Silverlight application that uses RIA Services. For this article I’ll use a C# project, but you can do the same with a Visual Basic project:
  1. Start a new Silverlight application by selecting File | New | andProject. You’ll see the New Project window in Figure 3.
  1. Select Visual C#, select Silverlight in Project types, and select Silverlight Application in Templates.
  2. Set Name to RIAServicesDemo, specify the Location where you want the project to reside, and click OK. You’ll see the New Silverlight Application window in Figure 4.

Figure 3: New Project window.
Figure 4: New Silverlight Application window.
If you’ve built Silverlight applications before, the New Silverlight Application window in Figure 4 will be familiar. The Host the Silverlight application in a new Web site check box creates a new ASP.NET Web site with sample pages containing the new Silverlight control. You can change the project name to anything you like, but this demo will use the default. This demo will also use the default of ASP.NET Web Application Project as the project type; the alternative being an ASP.NET Web Site project. What’s new, for Silverlight 4, in the New Silverlight Application window is the Link options section. To use RIA Services, you must check the box for Link to ASP.NET server project, which establishes the proper assembly references and any other settings required for using RIA Services. If you forget to check the Link to ASP.NET server project box and change your mind later, you can open the Properties window for the Silverlight project and there is an option called ASP.NET server project link on the Silverlight tab that you can change.
  1. Click OK to create a new solution with a Silverlight application project and an ASP.NET project, shown in Figure 5.

Figure 5: New RIA Services application solution.
A couple items in Figure 5 are worthy of mention: assembly references and Toolbox controls. Notice that the Silverlight project, RIAServicesDemo, includes a reference to System.Windows.Ria; the assembly containing RIA Services types. In addition, you can see several new controls in the Toolbox such as DataForm, DataPager, and DatePicker that are new in Silverlight 4.
There are more new controls, many that are members of the Silverlight Toolkit, which is a set of LoB controls for Silverlight 2 available at http://silverlight.codeplex.com. Later sections of this article will introduce you to a couple of the new data controls.
"

“RIA Services supports multiple types of DAL in your architecture, including LINQ to SQL, LINQ to Entities, or custom.”
"

Adding a Middle Tier with Domain Service
Now that you have a project in-place, you need to set up a data source and build a middle tier, which will consist of a Business Logic Layer (BLL) and a Data Access Layer (DAL). As shown in Figure 2, RIA Services supports multiple types of DAL in your architecture, including LINQ to SQL, LINQ to Entities, or custom. The Domain Service resides in the Web application, RiaServicesDemo.Web, which is your middle-tier project. This article uses LINQ to Entities for a DAL and then builds the BLL on top of that with a Domain Service.
Building the DAL
To get started, add an entity data model to the Web application, RiaServicesDemo.Web. As a refresher, you can right-click on the RiaServicesDemo.Web project, select Add, New Item, select ADO.NET Entity Model, and work through the wizard to add an AdventureWorks.edmx file that includes all of the database tables. You now have an entity data model named AdventureWorksLT_DataEntities and are ready to add a Domain Service.
Adding the BLL
The Domain Service builds a BLL that connects to a DAL based on the AdventureWorksLT_DataEntities entity data model just created. To build the Domain Service, right-click on the RiaServicesDemo.Web project, select Add, New Item, select Domain Service Class, name the file CustomerService.cs, and click OK. The New Domain Service Class, shown in Figure 6, has parameters to configure the behavior of your Domain Service, including enabling client access, DAL selection, which entities to base the service on, and which type of operations that the service supports.


Figure 6: New Domain Service Class window.
Check Enable client access to make the class discoverable by the Silverlight application. The Available DataContexts/ObjectContexts lists contains a list of LINQ to SQL DataContext and LINQ to Entities ObjectContext classes available in the Web application. Notice that the AdventureWorksLT_DataEntities entity data model is automatically selected as the DAL, since it is the only DataContext or ObjectContext available.
This application works with Customers so you need to check the Customer entity. Check Enable editing to enable insert, update, and delete support. In this article I won’t check Enable editing so the application will have read-only support.
I did not check Generate associated classes for metadata and won’t use it in this example; you use it to add metadata to auto-generated entities such as those generated by LINQ to Entities, which you don’t want to change directly. Click OK to generate the CustomerServiceclass, shown in Listing 1.
"

“The benefit is that all the classes are generated for you automatically and all you need to do is code your business logic.”
"
Inside the DomainService Class
The CustomerService class in Listing 1 derives fromLinqToEntiesDomainService>,is decorated with the EnableClientAccess attribute and contains aGetCustomers method, which are the direct result of settings in the New Domain Service Class window. Since the DAL is based on an ADO.NET Entity Framework data model,AdventureWorksLT_DataEntities, the base class isLinqToEntitiesDomainService>.Had the DAL been based on a LINQ to SQL entity model, the base class would have beenLinqToSqlDomainService>.The EnableClientAccess attributes makes the CustomerServiceclass discoverable by the Silverlight application, the implementation which you’ll soon read about in a later section of this article.
Since you selected the Customer entity, there is a GetCustomersmethod that will return an IQueryable collection. The implementation of GetCustomers is particularly interesting because it references the base class Context property, which contains an ObjectContext reference for AdventureWorksLT_DataEntities. In its initial implementation, GetCustomers returns all customers in the database. However, what you might like to know is that you can now add business logic before and after the call. This is much like the business object implementation that many n-layer applications implement. The benefit is that all the classes are generated for you automatically and all you need to do is code your business logic. In addition to the auto-generated methods, you’ll want to add more methods for custom operations such as the need to get a single customer as shown below:
public IQueryable GetCustomerByID( int customerID) { return from cust in Context.Customer where cust.CustomerID == customerID select cust; }
Just add the code above to the CustomerService class. Clients will find the new GetCustomerByID method, shown above, because theCustomerService class has the EnableClientAccess attribute. The Data Service is now ready to be consumed by a client.
Consuming a Domain Service in Silverlight 4
The Data Service, created in the last section, is automatically available to the Silverlight application; made possible because Link to ASP.NET server project was checked, as shown in Figure 4. First, build the entire solution to generate a proxy file in the Silverlight application. You can see the proxy by selecting the Silverlight application, RiaServicesDemo, and then clicking on the Show All Files toolbar button in Solution Explorer. You’ll see a Generated Code folder containing a file named RiaServicesDemo.Web.g.cs, which is the proxy for the CustomerService Domain Service.
The generated proxy is named CustomerContext, which corresponds to the CustomerService Domain Service. You will have an XxxContext proxy for every XxxService Domain Service in your Web application. What is particularly useful about this proxy is a set of Load methods for each of the Get methods in the Domain Service. RIA Services uses a convention based on pre-defined prefixes to determine which methods to generate a proxy Load method for, including any methods that start with Get, Fetch, Find, Query, orSelect. Therefore, the Domain Service method GetCustomer could have been named SelectCustomer and the proxy would have still been generated with the corresponding LoadCustomer method.
To see how to consume data, I’ll display Customer data on a Silverlight user control. Add a DataGrid to the MainPage.xaml page and a new handler to the UserControl Loaded event in RiaServicesDemo, as shown in Listing 2.
In Listing 2, the grid will show all customers and the Loaded event handler, UserControl_Loaded, will retrieve data and load the grid. Remember to remove line wrapping in Listing 2 namespaces, which I added for article formatting. Listing 3 shows how theUserControl_Loaded event handler is implemented to retrieve and display customer data.
The first thing to point out in Listing 3 is the using declaration forRiaServicesDemo.Web, which is the namespace generated for the proxy. Next, you can see the implementation of theUserControl_Loaded event handler. After getting a reference to theCustomerContext proxy, the code assigns the Customers property of the proxy to the CustomerDataGrid, but the data does not bind at that point in time. The data really binds asynchronously, courtesy of the LoadCustomer method. Figure 7 shows the Silverlight application in the browser, displaying customer data.
Figure 7: Silverlight application consuming and displaying customer data via RIA Services.
"

“The beauty of the asynchronous binding pattern is that the Load method, LoadCustomer, of the proxy, CustomerContext, saves you from having to write the asynchronous code yourself.”
"
Remember, the Silverlight user control is running in the browser, but the Web application is where the Data Service, CustomerService, resides. To avoid timeouts and to keep the UI in the browser responsive, LoadCustomer performs an asynchronous call to theGetCustomer method on the server. When the data arrives back at the browser, LoadCustomer takes care of binding it to theCustomerDataGrid. This is why you might see a delay between the time the page starts and when the data actually appears when running the application. The beauty of the asynchronous binding pattern is that the Load method, LoadCustomer, of the proxy,CustomerContext, saves you from having to write the asynchronous code yourself.
Summary
Looking at n-tier implementations with Web services and comparing that with RIA Services should give you an idea of the types of problems the RIA Services solves and the points of productivity to be gained. You now know what tools are available and how to build an RIA Services project. The discussion led you through the techniques used with Data Services to create a middle-tier set of components, holding BLL and DAL layers of your architecture. You then learned how to consume the Data Service via an auto-generated proxy in a Silverlight application. This should give you a good idea of the benefits of RIA Services and how it will help you build LoB applications faster with Silverlight 4.
Looking Forward
This article demonstrated how easy it is to produce and consume data via RIA Services, but there is much more to explore. RIA Services also allows full CRUD operations, shared validation between tiers, and additional metadata support. Keep an eye on Nikhil Kothari’s and Brad Abram’s blogs at http://www.nikhilk.net andhttp://blogs.msdn.com/brada, respectively. Of course, don’t forget to come back to CODE Magazine for more articles on RIA Services.
Joe Mayo


Listing 1: The CustomerService Domain Service class
namespace RiaServicesDemo.Web { using System; using System.Collections.Generic; using System.ComponentModel; using System.ComponentModel.DataAnnotations; using System.Linq; using System.Web.Ria; using System.Web.Ria.Data; using System.Web.DomainServices; using System.Data; using System.Web.DomainServices.LinqToEntities; // Implements application logic using the // AdventureWorksLT_DataEntities context. // TODO: Add your application logic to these // methods or in additional methods. [EnableClientAccess()] public class CustomerService : LinqToEntitiesDomainService { // TODO: Consider // 1. Adding parameters to this method and // constraining returned results, and/or // 2. Adding query methods taking different // parameters. public IQueryable GetCustomer() { return this.Context.Customer; } } }

Listing 2: Configuring a Silverlight User Control UI for displaying customers
<UserControl xmlns:data="clr-namespace:System.Windows.Controls; assembly=System.Windows.Controls.Data" x:Class="RiaServicesDemo.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/ presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Width="400" Height="300" Loaded="UserControl_Loaded"> <Grid x:Name="LayoutRoot" Background="White"> <data:DataGrid Name="CustomerDataGrid"> data:DataGrid> <data:DataGrid Name="CustomerDataGrid"> data:DataGrid> Grid> UserControl>

Listing 3: Retrieving and displaying customer data with the CustomerContext proxy
using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Windows; using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Shapes; using RiaServicesDemo.Web; namespace RiaServicesDemo { public partial class MainPage : UserControl { public MainPage() { InitializeComponent(); } private void UserControl_Loaded( object sender, RoutedEventArgs e) { var ctx = new CustomerContext(); CustomerDataGrid.ItemsSource = ctx.Customers; ctx.LoadCustomer(); } } }

Building N-Tier business applications with .NET RIA Services

This article is compatible with the latest version of Silverlight.

Introduction

In this series of articles we will talk about building N-Tier Silverlight business application, why we want to use multiple tiers, what problems we have to face and how .NET RIA Services can help us solve our issues.

Going N-Tier

If you develop complex business applications with a large codebase that can easily adapt to changing environments you introduce multiple tiers or layers. For example, you create a Data Access Layer that communicates with your data source whatever that is and passes the requested data to the layer above in object oriented form. The layers above don’t know and don’t want to know anything about how persistence actually happens. All that they want to do is: GetProducts, SaveChanges or PersistChanges. You can have many different layers like Business Logic Layer, Service Layer or Presentation Layer to ensure your code is flexible, well-structured and strictly separated.
So you decided going n-tier which is not a really big surprise since you don’t have a choice. If you work with Silverlight you have at least 3 layers. You don’t have ADO.NET libraries in Silverlight so you can’t interact with a database directly (and you shouldn’t do that anyway). So here is what you should have (at least):
1. Your Silverlight Application - Presentation layer
2. A WCF Service – Service Layer
3. Your Database / additional ADO.NET logic to interact with your database – Persistence Layer

Issues with N-Tier development

You have a nice architecture now but it introduces new problems. Now let’s think about how you want to code against these layers. In your Presentation Layer you would like to call a GetProducts method and retrieve your Product list from your Service Layer. You do whatever you want with this list. You modify Product instances in it, add new ones or delete old ones. After you’re done all you want to do is “SaveChanges” back to the database. But you can’t. This would mean that you have client-side change tracking and identity management. Even if you had this on the server side you had lost it as soon as your data has left the server. Solving this problem by yourself would mean a lot of code.

Building a Service Layer Manually for CRUD Support

If you have several entities mapped to tables on the server side you probably want to enable CRUD operations on them. In this case you’d have to write all these operations by yourself. For example, CRUD operations for the Product entity would look something like this:
  • GetProducts
  • InsertProduct(Product p)
  • DeleteProduct(Product p)
  • UpdateProduct(Product p)

Validation issues

Now, if you want to save changes created by user input back to the database you need validation. When you use technologies like Entity Framework or LinqToSql you may notice that the entities setters contain a call to a partial method where you can handle validation. And we know that Silverlight validation mechanism is based on throwing exceptions in property setters. So this is pretty much the place where you should write this logic. Validation needs to happen on both client and server side. Server-side validation ensures that invalid data sent by hacked clients won’t cause any problems. Client-side validation will save us round-trips back to the server.
So you have to write the logic on server-side… but serialization mechanisms serialize only data, not logic, so on the client-side you won’t have the validation logic that you implemented on server-side. That means that you have to duplicate your code and maintain the synchronization of validation logic between the client and the server manually.

Restrictions based on Authentication and Authorization

You support full CRUD and custom operations but maybe only authenticated users are capable of submitting an order or only administrators are allowed to delete or insert a new product. You want to define custom operations that can be executed only by certain users or by users in certain roles. Which means that you’ll have to implement authentication and authorization almost from scratch.

Introducing .NET RIA Services

As we discussed earlier, going N-Tier is inevitable but certainly necessary even if it means writing a lot of code. Fortunately, there is a technology called .Net RIA services that can help you out with these issues. .NET RIA Services can offer you out of the box solutions for the issues mentioned above.
If you install .NET RIA Services you’ll get new Silverlight application templates in Visual Studio. One of the new templates is theSilverlight Business Application template. This template generates a solution structure that provides a lot of functionality out of the box. If you run the empty project you’ll see that you have an application that supports navigation. You already have a home and an about page, it has a nice error window to display error messages (just try to navigate to a page that does not exist yet to see it) and it has a login and a register window as well. If you take a closer look at the project structure in the ASP.NET project you’ll see a Services folder where you can find prepared services for supporting user related operations like registration or login.

The structure of a DomainService

.NET RIA Services defines a class called DomainService which services as a base class to your Domain Services. A domain service contains different operations like CRUD or custom operations and is completely independent of the underlying layers. Let’s take a look at how a domain service implementation looks like:
 [EnableClientAccess()]
 public class SampleDomainService : DomainService
 {    
  public IQueryable GetProducts()
     {         return DataAccessLayer.ProductRepository.GetProducts();
     }
 }
Our SampleDomainService inherits from the DomainService abstract base class and it is decorated with theEnableClientAccessAttribute. This attribute means that the service will be visible from the client-side and static code generation will create the necessary client-side proxy objects.
Now we have a GetProducts method. The method returns an IQueryable which means that this operation can be part of a more complex query. GetProducts will be the source of the complex query and any additional query methods can be appended to it. The actual implementation of the method could be anything. In this case it forwards the request to a custom data access layer. A “select” method must meet the following requirements:
  • returns IQuerable, IEnumerable or a singleton instance of type T
  • It should take 0 or more parameters
  • It may be decorated with the QueryAttribute to explicitly indicate the method as a query method

The structure of a Domain Context

Now if you build the project and you click show all files on the Silverlight Project you’ll get an [ApplicationName].Web.g.cs file in theGenerated_Code folder. Let’s see what’s inside:
 public sealed partial class SampleDomainContext : DomainContext
 {
     public EntityList Products
    {
         get
         {
             return base.Entities.GetEntityList();
         }
     }   
     public EntityQuery GetProductsQuery()
     {
         return base.CreateQuery("GetProducts", null, false, true);
     }
 ...
As you can see with static code generation without using Add Service Reference…, a DomainContext was created for you. Domain Context provides identity management, change tracking and operation invocation. This is the client context for your server-side domain service. You can compose complex queries using the GetProductsQuery method. As you can see it creates an EntityQuerythat calls GetProducts on the server-side. The results of the query will be loaded into the exposed Products property of typeEntityList. EntityList is a very friendly collection with rich data binding support.
So what happened? Static code generation happened based on conventions. We exposed a DomainService and defined a method that met some requirements in order to be identified as a query operation. A domain context was created on the client-side with access to our domain service and to our domain operation.

Writing a Simple Query using DomainContext

Now all you have to do is to create a query, run it and load the results into a DataGrid for example. Creating a query can be done in code-behind using a domain context instance:
 SampleDomainContext ctx = new SampleDomainContext();
  
 var query = from p in ctx.GetProductsQuery()
             where p.Discontinued == false
             select p;
  
 dataGrid.ItemsSource = ctx.Products;
 ctx.Load(query);
We used the GetProductsQuery() to serve as the source of the query composition. The DataGrid’s ItemsSource property is assigned to the domain context’s Products property of type Entity List which implements INotifyCollectionChanged so as soon as the data is loaded into the property it will be displayed on the UI.
Finally we have to explicitly call the Load method passing the composed EntityQuery as a parameter. This operation calls the domain service and fills up our local EntityList and of course it is done asynchronously.

Summary

In this introduction article we learned why using n-tier architecture is necessary and what kind of issues do we have to face. .NET RIA services aims to solve most of our problems using convention based static code generation. We got to know two important objects - the DomainService and the DomainContext.
Later we will see that more complex queries can be written and they can also be composed declaratively in XAML using aDomainDataSource object.

Thursday, March 15, 2012

Silverlight vs. (Html + JQuery)-MVC

Silverlight and jQuery "may be" intended for similar things, rich user interface, but Silverlight has a complete framework that utilizes the power of .NET and provide rich feature set.

Some "time" back, I was given a choice to decide between jQuery and Silverlight.

I did not delve into the discussion of what Silverlight is and what ASP.NET MVC + Jquery + html for a web application. is. I just presented the solution, using jQuery for MVC application, Silverlight if its intranet based.

First, please understand that Silverlight is not Macromedia Flash. It is far more superior, and elegant; -- and -- it has the "capabilities" of Flash.

1). For competitive reasons you may want to stick with MVC at the time being. Silverlight is a great technology but not everyone has the plugin yet. If you write standards compliant HTML / CSS etc. with an MVC site your users will not have to download any additional plug-ins; just a browser. It depends on your application.

2). If you want mobile support today Silver-light doesn’t have it so MVC wins.

In all other cases, Silverlight will usually make more sense – because it costs so much less to maintain and upgrade the site:

To do Silverlight you need expertise in:

  1. XAML
  2. A .NET language

To do MVC you need expertise in:

  1. A .NET language
  2. MVC
  3. ASP.NET
  4. HTML
  5. CSS
  6. Browser compatibility (present, past and future)
  7. Javascript
  8. JQuery

Why would an employer want to pay to keep someone up to date in all those skills?

I’ve answered this to the best of my ability, through my opinions shared below.

3). Why can’t you use both?

The real question here is not Technology X vs. Technology Y. More likely it is:

What technology or set of technologies will help me accomplish my goal in the most effective way possible?

Browser Plugin

Generally speaking, a browser plugin (Flash, Silverlight) is going to give you a lot of power in terms of rich user experience that would be difficult or impossible to duplicate using pure JavaScript. It is also a different programming paradigm, because it is a stateful application running inside the browser.

HTML + JavaScript

JQuery is just one of many JavaScript frameworks out there for building rich client experiences for your web application. It offers a lot of flexibility, and has a very broad reach, but at the end of the day you are still working with the DOM, and will be limited to what can be accomplished using JavaScript and angle brackets. This is also a stateless programming paradigm so you need to understand how that fits in with your overall architecture when designing your application.

Hybrid

More than likely you will be able to take advantage of both. Figure out what sub-section of your application really needs rich user interaction, and code that in Flash/Silverlight or whatever you want. The rest of your site can be done AJAX style with whatever combination of server/client frameworks you want. If you like JQuery, go with it, but don’t discount other frameworks just because JQuery is all the rage right now.

I had to research some weeks ago on which UI technology would be the best choice for the applications that my client has and is going to build in the next couple of years. We are a .NET shop, so there are 2 major directions you could move into: standards-based web development, or Silverlight.

When you have to recommend one over the other, you ideally want to be able to back up your choice with more than just some opinions.

Silverlight scores very badly for a web-apps’s designing and implementing strategies, the fact that it’s not standards-compliant(like usual MS products) obviously hurts. But there’s more to it than that. First of all, the ‘Mobile’ story pretty much kills it (Android and iOS don’t support it, Microsoft hasn’t even announced a Silverlight browser plugin for WP7 yet and who knows if it will? That means that Silverlight web applications aren’t usable on any mobile device right now).

But there are several areas where SilverLight scores better than ASP.NET – MVC3 with jQuery: When it comes to Tools, you can’t deny the fact that Visual Studio and Blend cover a lot of ground when it comes to the whole Silverlight developer experience. At the very least, you can mostly stick to your familiar integrated environment, whereas with standards-based web development, you’re likely to spend some time in Firebug or Google Chrome’s developer tools instead of sticking almost entirely with Visual Studio.

The biggest benefit that Silverlight has over standards-based web development is that you only need to know C# and XAML. With standards-based web development, you have to know HTML, CSS, JavaScript and the language of your server-side technology, in this case also C#. This might impact your ability to find new developers so Silverlight does have sort of an advantage there.

From a security point of view, Silverlight also scores better because you don’t really have to worry about common issues such as XSS, CSRF and other vulnerabilities that are common in web-development.

You can download the analysis spreadsheet here.

Conclusion

In the end, do your homework, and make an informed decision. You will be happier having learned the pros and cons of multiple technologies and frameworks, and chosen one based on your needs, not just because someone on SO told you that X technology was awesome so you should only ever use it.