Gunnar Peipman's ASP.NET blog

ASP.NET, C#, SharePoint, SQL Server and general software development topics.

Sponsors

News

 
 
 
DZone MVB

Links

Social

December 2010 - Posts

ASP.NET: Serializing and deserializing JSON objects

ASP.NET offers very easy way to serialize objects to JSON format. Also it is easy to deserialize JSON objects using same library. In this posting I will show you how to serialize and deserialize JSON objects in ASP.NET.

All required classes are located in System.Servicemodel.Web assembly. There is namespace called System.Runtime.Serialization.Json for JSON serializer.

To serialize object to stream we can use the following code.


var serializer = new DataContractJsonSerializer(typeof(MyClass));

serializer.WriteObject(myStream, myObject);


To deserialize object from stream we can use the following code. CopyStream() is practically same as my Stream.CopyTo() extension method.


var serializer = new DataContractJsonSerializer(typeof(MyClass));

 

using(var stream = response.GetResponseStream())

using (var ms = new MemoryStream())

{

    CopyStream(stream, ms);

    results = serializer.ReadObject(ms) as MyClass;

}


Why I copied data from response stream to memory stream? Point is simple – serializer uses some stream features that are not supported by response stream. Using memory stream we can deserialize object that came from web.

Stream.CopyTo() extension method

In one of my applications I needed copy data from one stream to another. After playing with streams a little bit I wrote CopyTo() extension method to Stream class you can use to copy the contents of current stream to target stream. Here is my extension method.

It is my working draft and it is possible that there must be some more checks before we can say this extension method is ready to be part of some API or class library.


public static void CopyTo(this Stream fromStream, Stream toStream)

{

    if (fromStream == null)

        throw new ArgumentNullException("fromStream");

    if (toStream == null)

        throw new ArgumentNullException("toStream");

 

    var bytes = new byte[8092];

    int dataRead;

    while ((dataRead = fromStream.Read(bytes, 0, bytes.Length)) > 0)

        toStream.Write(bytes, 0, dataRead);

}


And here is example how to use this extension method.


using(var stream = response.GetResponseStream())

using(var ms = new MemoryStream())

{

    stream.CopyTo(ms);
 

    // Do something with copied data

}


I am using this code to copy data from HTTP response stream to memory stream because I have to use serializer that needs more than response stream is able to offer.

Posted: Dec 28 2010, 03:24 AM by DigiMortal | with 12 comment(s)
Filed under: ,
ASP.NET and WIF: Showing custom profile username as User.Identity.Name

I am building ASP.NET MVC application that uses external services to authenticate users. For ASP.NET users are fully authenticated when they are redirected back from external service. In system they are logically authenticated when they have created user profiles. In this posting I will show you how to force ASP.NET MVC controller actions to demand existence of custom user profiles.

Using external authentication sources with AppFabric

Suppose you want to be user-friendly and you don’t force users to keep in mind another username/password when they visit your site. You can accept logins from different popular sites like Windows Live, Facebook, Yahoo, Google and many more. If user has account in some of these services then he or she can use his or her account to log in to your site.

If you have community site then you usually have support for user profiles too. Some of these providers give you some information about users and other don’t. So only thing in common you get from all those providers is some unique ID that identifies user in service uniquely.

Using AppFabric ACS to identify users

Image above shows you how new user joins your site. Existing users who already have profile are directed to users homepage after they are authenticated. You can read more about how to solve semi-authorized users problem from my blog posting ASP.NET MVC: Using ProfileRequiredAttribute to restrict access to pages.

The other problem is related to usernames that we don’t get from all identity providers.

Why is IIdentity.Name sometimes empty?

The problem is described more specifically in my blog posting Identifying AppFabric Access Control Service users uniquely. Shortly the problem is that not all providers have claim called http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name. The following diagram illustrates what happens when user got token from AppFabric ACS and was redirected to your site.

How IIdentity.Name gets value from WIF

Now, when user was authenticated using Windows Live ID then we don’t have name claim in token and that’s why User.Identity.Name is empty. Okay, we can force nameidentifier to be used as name (we can do it in web.config file) but we have user profiles and we want username from profile to be shown when username is asked.

Modifying name claim

Now let’s force IClaimsIdentity to use username from our user profiles. You can read more about my profiles topic from my blog posting ASP.NET MVC: Using ProfileRequiredAttribute to restrict access to pages and you can find some useful extension methods for claims identity from my blog posting Identifying AppFabric Access Control Service users uniquely.

Here is what we do to set User.Identity.Name:

  • we will check if user has profile,
  • if user has profile we will check if User.Identity.Name matches the name given by profile,
  • if names does not match then probably identity provider returned some name for user,
  • we will remove name claim and recreate it with correct username,
  • we will add new name claim to claims collection.

All this stuff happens in Application_AuthorizeRequest event of our web application. The code is here.


protected void Application_AuthorizeRequest()

{

    if (string.IsNullOrEmpty(User.Identity.Name))

    {

        var identity = User.Identity;

        var profile = identity.GetProfile();

        if (profile != null)

        {

            if (profile.UserName != identity.Name)

            {

                identity.RemoveName();

 

                var claim = new Claim("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name", profile.UserName);

                var claimsIdentity = (IClaimsIdentity)identity;

                claimsIdentity.Claims.Add(claim);

            }

        }

    }

}


RemoveName extension method is simple – it looks for name claims of IClaimsIdentity claims collection and removes them.


public static void RemoveName(this IIdentity identity)

{

    if (identity == null)

        return;

 

    var claimsIndentity = identity as ClaimsIdentity;

    if (claimsIndentity == null)

        return;

 

    for (var i = claimsIndentity.Claims.Count - 1; i >= 0; i--)

    {

        var claim = claimsIndentity.Claims[i];

        if (claim.ClaimType == "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name")

            claimsIndentity.Claims.RemoveAt(i);

    }

}


And we are done. Now User.Identity.Name returns the username from user profile and you can use it to show username of current user everywhere in your site.

Conclusion

Mixing AppFabric Access Control Service and Windows Identity Foundation with custom authorization logic is not impossible but a little bit tricky. This posting finishes my little series about AppFabric ACS and WIF for this time and hopefully you found some useful tricks, tips, hacks and code pieces you can use in your own applications.

ASP.NET MVC: Using ProfileRequiredAttribute to restrict access to pages

If you are using AppFabric Access Control Services to authenticate users when they log in to your community site using Live ID, Google or some other popular identity provider, you need more than AuthorizeAttribute to make sure that users can access the content that is there for authenticated users only. In this posting I will show you hot to extend the AuthorizeAttribute so users must also have user profile filled.

Semi-authorized users

When user is authenticated through external identity provider then not all identity providers give us user name or other information we ask users when they join with our site. What all identity providers have in common is unique ID that helps you identify the user.

Example. Users authenticated through Windows Live ID by AppFabric ACS have no name specified. Google’s identity provider is able to provide you with user name and e-mail address if user agrees to publish this information to you. They both give you unique ID of user when user is successfully authenticated in their service.

There is logical shift between ASP.NET and my site when considering user as authorized.

For ASP.NET MVC user is authorized when user has identity. For my site user is authorized when user has profile and row in my users table. Having profile means that user has unique username in my system and he or she is always identified by this username by other users.

Community site & ASP.NET MVC: Is user authorized?

My solution is simple: I created my own action filter attribute that makes sure if user has profile to access given method and if user has no profile then browser is redirected to join page.

Illustrating the problem

Usually we restrict access to page using AuthorizeAttribute. Code is something like this.


[Authorize]

public ActionResult Details(string id)

{

    var profile = _userRepository.GetUserByUserName(id);

    return View(profile);

}


If this page is only for site users and we have user profiles then all users – the ones that have profile and all the others that are just authenticated – can access the information. It is okay because all these users have successfully logged in in some service that is supported by AppFabric ACS.

In my site the users with no profile are in grey spot. They are on half way to be users because they have no username and profile on my site yet. So looking at the image above again we need something that adds profile existence condition to user-only content.


[ProfileRequired]

public ActionResult Details(string id)

{

    var profile = _userRepository.GetUserByUserName(id);

    return View(profile);

}


Now, this attribute will solve our problem as soon as we implement it.

ProfileRequiredAttribute: Profiles are required to be fully authorized

Here is my implementation of ProfileRequiredAttribute. It is pretty new and right now it is more like working draft but you can already play with it.


public class ProfileRequiredAttribute : AuthorizeAttribute

{

    private readonly string _redirectUrl;

 

    public ProfileRequiredAttribute()

    {

        _redirectUrl = ConfigurationManager.AppSettings["JoinUrl"];

        if (string.IsNullOrWhiteSpace(_redirectUrl))

            _redirectUrl = "~/";

    }       

 

    public override void OnAuthorization(AuthorizationContext filterContext)

    {

        base.OnAuthorization(filterContext);

 

        var httpContext = filterContext.HttpContext;

        var identity = httpContext.User.Identity;

 

        if (!identity.IsAuthenticated || identity.GetProfile() == null)

            if(filterContext.Result == null)

                httpContext.Response.Redirect(_redirectUrl);     

    }

}


All methods with this attribute work as follows:

  • if user is not authenticated then he or she is redirected to AppFabric ACS identity provider selection page,
  • if user is authenticated but has no profile then user is by default redirected to main page of site but if you have application setting with name JoinUrl then user is redirected to this URL.

First case is handled by AuthorizeAttribute and the second one is handled by custom logic in ProfileRequiredAttribute class.

GetProfile() extension method

To get user profile using less code in places where profiles are needed I wrote GetProfile() extension method for IIdentity interface. There are some more extension methods that read out user and identity provider identifier from claims and based on this information user profile is read from database. If you take this code with copy and paste I am sure it doesn’t work for you but you get the idea.


public static User GetProfile(this IIdentity identity)

{

    if (identity == null)

        return null;

 

    var context = HttpContext.Current;

    if (context.Items["UserProfile"] != null)

        return context.Items["UserProfile"] as User;

 

    var provider = identity.GetIdentityProvider();

    var nameId = identity.GetNameIdentifier();

 

    var rep = ObjectFactory.GetInstance<IUserRepository>();

    var profile = rep.GetUserByProviderAndNameId(provider, nameId);

 

    context.Items["UserProfile"] = profile;

 

    return profile;

}


To avoid round trips to database I cache user profile to current request because the chance that profile gets changed meanwhile is very minimal. The other reason is maybe more tricky – profile objects are coming from Entity Framework context and context has also HTTP request as lifecycle.

Conclusion

This posting gave you some ideas how to finish user profiles stuff when you use AppFabric ACS as external authentication provider. Although there was little shift between us and ASP.NET MVC with interpretation of “authorized” we were easily able to solve the problem by extending AuthorizeAttribute to get all our requirements fulfilled. We also write extension method for IIdentity that returns as user profile based on username and caches the profile in HTTP request scope.

ASP.NET: Including JavaScript libraries conditionally from CDN

When developing cloud applications it is still useful to build them so they can run also on local machine without network connection. One thing you use from CDN when in cloud and from app folder when not connected are common JavaScript libraries. In this posting I will show you how to add support for local and CDN script stores to your ASP.NET MVC web application.

Our solution is simple. We will add new configuration setting to our web.config file (including cloud transform file of it) and new property to our web application. In master page where scripts are included we will include scripts from CDN conditionally. There is nothing complex, all changes we make are simple ones.

1. Adding new property to web application

Although I am using ASP.NET MVC web application these modifications work also very well with ASP.NET Forms. Open Global.asax and add new static property to your application class.


public static bool UseCdn

{

    get

    {

        var valueString = ConfigurationManager.AppSettings["useCdn"];

        bool useCdn;

 

        bool.TryParse(valueString, out useCdn);

        return useCdn;

    }

}


If you want less round-trips to configuration data you can keep some nullable boolean in your application class scope and load CDN setting first time it is asked.

2. Adding new configuration setting to web.config

By default my application uses local scripts. Although my application runs on cloud I can do a lot of stuff without staging environment in cloud. So by default I don’t have costs on traffic when including scripts from application folders.


<appSettings>

  <add key="UseCdn" value="false" />

</appSettings>


You can also set UseCdn value to true and change it to false when you are not connected to network.

3. Modifying web.config cloud transform

I have special configuration for my solution that I use when deploying my web application to cloud. This configuration is called Cloud and transform for this configuration is located in web.cloud.config. To make application using CDN when deployed to cloud we need the following transform.


<appSettings>

  <add key="UseCdn"
      
value="true"
       xdt:Transform="SetAttributes"
      
xdt:Locator="Match(key)"
/>

</appSettings>


Now when you publish your application to cloud it uses CDN by default.

4. Including scripts in master pages

The last thing we need to change is our master page. My solution is simple. I check if I have to include scripts from CDN and if it is true then I include scripts from there. Otherwise my scripts will be included from application folder.


@if (MyWeb.MvcApplication.UseCdn)
{
    <script src="http://ajax.microsoft.com/ajax/jquery/jquery-1.4.4.min.js" type="text/javascript"></script>
}
else
{
    <script src="@Url.Content("~/Scripts/jquery-1.4.4.min.js")" type="text/javascript"></script>
}

Although here is only one script shown you can add all your scripts that are also available in some CDN in this if-else block. You are free to include scripts from different CDN services if you need.

Conclusion

As we saw it was very easy to modify our application to make it use CDN for JavaScript libraries in cloud and local scripts when run on local machine. We made only small changes to our application code, configuration and master pages to get different script sources supported. Our application is now more independent from external sources when we are working on it.

Identifying AppFabric Access Control Service users uniquely

In my last posting about AppFabric Labs Access Control Service I described how to get your ASP.NET MVC application to work with ACS. In this posting I will dig deeper into tokens and claims and provide you with some helper methods that you may find useful when authenticating users using AppFabric ACS. Also I will explain you little dirty secret of Windows Live ID.

What is inside token?

Token and claimsLet’s start with dissecting tokens. Token is like envelope that contains claims. Each claim carries some property of identity. By default we get the following claims from all identity providers:

  • name identifier – unique identifier for user that can be used to identify user (user can change his or her name in identity provider service but name identifier does not change),
  • identity provider – unique string that helps us detect identity provider that user used to authenticate to our web page.

As you can see from the image on right then token may contain more claims like claim for name and e-mail address. There can be also other claims if identity provider is able to provide them.

How claims are specified?

Claims are specified in web.config file when we add federation metadata definition to application using STS reference wizard. In my web.config there are following claims defined.

  • http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name
  • http://schemas.microsoft.com/ws/2008/06/identity/claims/role
  • http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier
  • http://schemas.microsoft.com/accesscontrolservice/2010/07/claims/identityprovider

You can find claims from microsoft.identitymodel block in web.config file.

Why Live ID gives us empty name?

This is the question that I had when I added ACS support to my ASP.NET MVC web application and here is the answer. Live ID returns for user only the name identifier and it does not introduce it as user name to Windows Identity Foundation. As there is no name claim then user name is left empty and you find weird situation where user is authenticated but there is no username.

When user is authenticated over Live ID we get back these claims:

  • http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier
  • http://schemas.microsoft.com/accesscontrolservice/2010/07/claims/identityprovider

The values are something like this:

  • nameidentifier - QwxVt0jBnEUFw7B2HgfsaWeSQXIzAXC9yUKWR780UepE=
  • identityprovider - uri:WindowsLiveID

As you can see there is no claim for user name and that’s why user name is empty.

What Google returns?

Here is what Google returns when I authenticate myself:

  • nameidentifier - https://www.google.com/accounts/o8/id?id=AItOawlMC8j0cW8013mWBkEwXs6MsV5ixZUmxks
  • emailaddress – mygoogleusername@gmail.com
  • name - Gunnar Peipman
  • identityprovider - Google

Google asks user if he or she allows ACS to access my name and e-mail address. If I agree then my name and address are given to my web application and I have username filled correctly when asking for current user.

What data we should save for users?

This is the good question to ask because some services allow users to change their name. And names are not unique. Consider the name John Smith. There are hundreds of guys who have this name. There maybe also hundreds of Mary Smiths and as some of them get married they change their last name (if they don’t marry some John Smith, of course).

To be maximally fool-proof we have to save the values of identityprovider and nameidentifier claims to our users database. This way we can avoid the situation where two different identity providers give us same nameidentifier for different users.

Here is my claims extension class you can use to get the values of these fields easily.


public static class IdentityExtensions

{

    public static string GetIdentityProvider(this IIdentity identity)

    {

        var claimsIndentity = identity as ClaimsIdentity;

        if (claimsIndentity == null)

            return string.Empty;

 

        var providerQuery = from c in claimsIndentity.Claims

                            where c.ClaimType == "http://schemas.microsoft.com/accesscontrolservice/2010/07/claims/identityprovider"

                            select c.Value;

        var provider = providerQuery.FirstOrDefault();

        return provider;

    }

 

    public static string GetNameIdentifier(this IIdentity identity)

    {

        var claimsIndentity = identity as ClaimsIdentity;

        if (claimsIndentity == null)

            return string.Empty;

 

        var providerQuery = from c in claimsIndentity.Claims

                            where c.ClaimType == "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier"

                            select c.Value;

        var provider = providerQuery.FirstOrDefault();

        return provider;

    }

}


And here is how we can use these extension methods.


var identity = User.Identity;

var provider = identity.GetIdentityProvider();

var nameId = identity.GetNameIdentifier();


What about names?

As some providers doesn’t support returning names we have two options:

  • avoid these providers (like I currently do),
  • ask new users for (unique) username or first and last name when they are joining.

Right now I am trying to work out solution for second option so I have easy way how to handle separate user names support easily so I don’t have to write tons of code for this simple thing.

Conclusion

Claims based authentication is powerful way to identify users and AppFabric ACS lets our sites to support different identity providers so we don’t have to write code for each one of them. As identity providers support different features and does not return us always all the data we would like to have we have to be ready to handle the situation (like Windows Live ID). As we saw it was still easy to identify users uniquely because data for this purpose is always given to us with token.

ASP.NET MVC 3: Using AppFabric Access Control Service to authenticate users

I had Windows Azure training this week and I tried out how easy or hard it is to get Access Control Service to work with my ASP.NET MVC 3 application. It is easy now but it was not very easy to get there. In this posting I will describe you what I did to get ASP.NET MVC 3 web application to work with Access Control Service (ACS). I will show you also some code you may find useful.

Prerequisites

To get started you need Windows Azure AppFabric Labs account. There is free version of Access Control Service you can use you try out how to add access control support to your applications. In your machine you need some little things:

After installing WIF runtime you have to restart you machine because otherwise SDK cannot understand that runtime is already there.

Setting up Access Control Service

When all prerequisites are installed you are ready to register your (first?) access control service. Your fun starts with opening the following URL in your web browser: https://portal.appfabriclabs.com/ and logging in with your Windows Live ID. I don’t put up pictures here, if you want to guide with illustrations feel free to check out ASP.NET MVC example from AppFabric Labs sample documentation.

I will show you one screenshot in this point and this is the most important one – your ACS control panel where you find all important operations.

AppFabric Access Control Service: Control panel
Click on image to see it at original size.

In short the steps are as follows.

  1. Add new project and give it meaningful name.
  2. If ACS is not activated after creating project then activate it.
  3. Navigate to ACS settings and open Identity Providers section (take a look at screenshot above).
  4. Add Google as identity provider (Windows Live ID is already there and you cannot remove it) and move back to ACS control panel.
  5. Click on Relaying Party Applications link and add settings for your application there (you can use localhost too). I registered http://localhost:8094/ as my local application and http://localhost:8094/error as my error page. When you application is registered move back to ACS control panel.
  6. Move to Rule Groups section, select default rule group that was created when you registered your application and click on Generate Rules link. Now all rules for claims will be created and after that you can move back to ACS control panel.
  7. Now move to Application Integration section and leave it open – you need soon one link from there.

Follow these steps carefully and look at sample documentation if you need. Don’t miss step nr 6 as this is not illustrated in sample documentation and if you are in hurry then you may miss this step easily.

STS references

AppFabric Access Control Service: STS referenceNow comes the most interesting and annoying part of the process you have to perform every time before you deploy your application to cloud and also after that to restore STS settings for development environment.

You can see STS reference on the image on right in red box. If you have more than one environment (more than one relaying party application) registered you need reference for every application instance. If you have same instance in two environments – common situation in development – then you have to generate this file for both environments.

The other option is to run STS reference wizard before deploying your application to cloud giving it cloud application URL. Of course, after deployment you should run STS reference wizard again to restore development environment settings. Otherwise you are redirected to cloud instance after authenticating your self on ACS.

Adding STS reference to your application

  1. Now right-click on your web application project and select Add STS Reference…
       AppFabric Access Control Service: Add STS reference
     
  2. Now you are asked for location web.config file and URL of your application for which you are adding STS reference.
     
    AppFabric Access Control Service: Insert application URL
      
    web.config location is filled automatically, you have to insert application URL and click Next button.
     
  3. You get some warnings about not using SSL etc but keep things as simple as possible when you are just testing. The next steps asks you about location of STS data.
      
    AppFabric Access Control Service: Insert federation metadata URL
     
    Select Use an Existing STS and insert URL from AppFabric settings (WS-Federation Metadata is the correct URL). Click Next.
     
  4. You are asked about certificated and other stuff in the following dialogs but right now you can ignore these settings. Just click Next until STS reference wizard has no more questions.

Okay, now you have STS reference set but this is not all yet. We need some little steps more to do before trying out our application.

Modifying web.config

We need some modifications to web.config file. Add these two lines to appSettings block of your web.config file.


<add key="enableSimpleMembership" value="false" />
<
add key="autoFormsAuthentication" value="false"
/>

Under system.web add the following lines (or change existing ones).


<authorization>
  <
deny users="?"
/>
</
authorization
>
<
httpRuntime requestValidationMode="2.0"
/>

If you get form validation errors when authenticating then turn request validation off. I found no better way to get XML-requests to my pages work normally.

Adding reference to Windows Identity Model

AppFabric Access Control Service: Reference to Microsoft.IdentityModel assemblyBefore deploying our application to Windows Azure we need local reference to Microsoft.IdentityModel assembly. We need this reference because this assembly cannot be found in cloud environment.

If you don’t want to reference this assembly in your code you have to make it part of web application project so it gets deployed.

I have simple trick for that – I just include assembly to my project from bin folder. It doesn’t affect compilation but when I deploy my application to cloud the assembly will be in package.

Adding error handler

Before we can test our application we need also error handler that let’s us know what went wrong when we face problems when authenticating ourselves.

I added special controller called Error to my web application and defined view called Error for it. You can find this view and controller code also from ACS sample projects. I took them from there.

Testing application

Run your application now. It should you redirect to authentication providers page show on following screenshot. This page is part of ACS.

AppFabric Access Control Service: Select identity provider

Select Google and log in. You should be redirected back to your application as authenticated user. You can see corner of my test page on the following screenshot.

AppFabric Access Control Service: I am authenticated through Google!

NB! For Windows Live ID you will get empty username and this seems to be issue that is – of course – by design. Hopefully MS works things out and makes also Live ID usable in ACS but right now – if you are not level 400 coder, don’t touch it – it means more mess than you need.

Conclusion

Adding AppFabric ACS support to ASP.NET MVC 3 web application was not such an easy thing to do like I expected. ASP.NET MVC 3 has some minor bugs (that’s why we needed to parameters to appSettings block) and in the beginning we are not very familiar with Winodws Identity Foundation. After some struggling on different problems I got it running and I hope you can make your applications run too if you follow my instructions.

AppFabric ACS is still in beta but it looks very promising. There is also Facebook and Yahoo! support available and hopefully they add more authentication options in the near future. ACS helps you identify your users easily and you don’t have to write code for each identity provider.

Comparing and updating database schemas using Visual Studio 2010

During development it is possible that database schema changes and usually it changes are same sure to come as tax office and death. Later we need to reflect these changes also to live databases and it is not very easy task to do manually. In this posting I will show you how Visual Studio 2010 database tools can help you to update database schema.

Visual Studio database projects

Visual Studio 2010: Database project

Suppose you have database project in Visual Studio 2010. Screenshot on right shows you fragment of my example database with couple of tables. Of course, there are also other objects defined like primary keys, foreign keys, views and indexes.

Some people don’t like the idea about database projects and their extreme granularity but I like it. Steps to build database this way are not quickest one but also not too painful. I have time to think about my database schema and all important aspects get my full attention.

One good thing about database projects is that they also support versioning. It is easy to rollback changes I don’t want to keep. When other developers change database schema then I will get these changes when I update my codebase to last version from source code repository.

Now let’s see how I get some changes to other database after I am finished my current tasks and my code works like expected.

Adding schema comparison

One of the folders in your database project is titled as Schema Comparisons. Right-click on this folder and select Add => Schema Comparison. You are asked now for source and target schemas. Database connection you are using in your database project is automatically selected as source schema. Target schema must be given now.

Visual Studio 2010: Select source/target schema

NB! Make sure you have sysadmin permissions for target schema – otherwise you may have troubles generating update script.

As a next thing you have to set some options. I made sure in options that some database level objects are not compared. I really need to upgrade only database objects that are related to data (tables, views, stored procedures, indexes etc).

Visual Studio 2010: Schema compare options

Now you are done with your settings and it is time to compare schemas. Click OK in this window.

Comparing schemas

To start comparing schemas click OK button in source and target schemas window. Visual Studio starts with comparing right away. You can see my example results here.

Visual Studio 2010: Differences between source and target schemas
Click on image to see it at original size.

You can see that for some tables there is update action Skip – these tables have no changes. Some tables must be created during to target database. If there are tables that are changed then for these tables there will be action called Update. When we step in this table we can see diffs in Object Definitions tab.

NB! In this point I suggest you to save schema comparison. Otherwise comparison settings are not saved and you have to start from zero next time you run comparison.

Updating target schema

Now as you know changes that need to be done to target schema it is time to decide how we do these changes. We can let Visual Studio to do it but we can also export update script to new editor window or to some file.

Visual Studio 2010: Export updates to file

I am lazy guy and I will hit Write Updates button. After giving my confirmation Visual Studio makes changes to my target schema and notifies me when changes are done.

Is it always so nice? Not really. This was here just a quick start, a beginning of highway to hell. There are situations when schema updates are not easy and updates may even be conflicting. By example, if you add non-null columns to database tables that contain data and these columns have no default value specified then the update cannot be done automatically.

Conclusion

As we saw then comparing database schemas and updating target schema using Visual Studio 2010 database tools was easy and straight-forward process. We were able to say what objects we want to left out from comparison and we were able to get very good overview about changes that we need to make to target schema. Also it was easy to update target schema.

Deployable dependencies in Visual Studio 2010 SP1 Beta

One new feature that comes with Visual Studio 2010 SP1 Beta is support for deployment references. Deployment reference means that you can include all necessary DLL-s to deployment package so your application has all assemblies it needs to run with it in deployment package. In this posting I will show you how to use deployment dependencies.

When I open my ASP.NET web application I have new option for references when I right-click on my web project: Add Deployable Dependencies…

Visual Studio 2010 SP1 Beta: Add deployable dependencies

If you select it you will see dialog where you can select dependencies you want to add to your project package.

Visual Studio 2010 SP1 Beta: Select deployable dependencies

When packages you need are selected click OK. Visual Studio adds new folder to your project called _bin_DeployableAssemblies.

Visual Studio 2010 SP1 Beta: Deployable references for RazorScreenshot on right shows the list of assemblies added for ASP.NET Pages and Razor. All DLL-s required to run ASP.NET MVC 3 with Razor view engine are here. I am not sure if NuGet.Core.dll is required in production but if it is added then let it be there.

Deploy to Azure

I tried to deploy my ASP.NET MVC project that uses Razor to Windows Azure after adding deployable references to my project.

Deployment went fine and web role instance started without any problems. The only DLL reference I made as local was the one for System.Web.Mvc. All Razor stuff came with deployable dependencies.

Conclusion

Visual Studio support for deployable dependencies is great because this way component providers can build definitions for their components so also assemblies that are loaded dynamically at runtime will be in deployment package.

Visual Studio 2010 SP1 Beta supports IIS Express

Visual Studio 2010 SP1 Beta and ASP.NET MVC 3 RC2 were both announced today. I made a little test on one of my web applications to see how Visual Studio 2010 works with IIS Express. In this posting I will show you how to make your ASP.NET MVC 3 application work with IIS Express.

Installing new stuff

My old laptop installs Visual Studio 2010 SP1 BetaYou can install IIS Express using Web Platform Installer. It is not part of WebMatrix anymore and you can just install IIS Express without WebMatrix.

NB! You have to install IIS Express using Web Platform installer because IIS Express is not installed by SP1.

After installing Visual Studio 2010 SP1 Beta on my machine (it took a long-long-long time to install) I installed also ASP.NET MVC 3 RC2.

If you have Async CTP installed on your machine you have to uninstall it to get ASP.NET MVC 3 RC2 installed and run without problems.

Screenshot on right shows what kinf of horrors my old laptop had to survive to get all new stuff installer.

Setting IIS Express as server for web application

Now, when you right-click on some web project you should see new menu item in context menu – Use IIS Express….

VS2010 & IIS Express: Make web application use IIS Express

If you click on it you are asked for confirmation and if you say Yes then your web application is reconfigured to use IIS Express. After configuration you will see dialog box like this.

VS2010 & IIS Express: Web application URL on IIS Express

And you are done. You can run your application now.

Running web application

When you run your application it is run on IIS Express. You can see IIS Express icon on taskbar and when you click it you can open IIS Express settings.

VS2010 & IIS Express: Application running on IIS Express

If you closed your application in browser you can open it again from IIS Express icon.

Modifying IIS Express settings for web application

You can modify IIS Express settings for your application. Just open your project properties and move to Web tab.

VS2010 & IIS Express: Web application settings

IIS and IIS Express are using same settings. The difference is if you make check to Use IIS Express checkbox or not.

Switching back to Visual Studio Development Server

If you don’t want or you can’t use IIS Express for some reason you can easily switch back to Visual Studio Development Server. Just right-click on your web application project and select Use Visual Studio Development Server from context menu.

VS2010 & IIS Express: Use Visual Studio Development Server

Conclusion

IIS Express is more independent than full version of IIS and it can be also installed and run on machines where are very strict rules (some corporate and academic environments by example). IIS Express was previously part of WebMatrix package but now it is separate product and Visual Studio 2010 has very nice support for it thanks to SP1. You can easily make your web applications use IIS Express and if you want to switch back to development server it is also very easy.

More Posts Next page »