- | rssFeed | My book on MSBuild and Team Build | Archives and Categories Tuesday, May 26, 2009

Visual Studio 2010: When *Might* it be Available

Before I begin this post I must say that I do not have any inside information about the release of Visual Studio 2010 or .NET 4. The post is composed of 100 % speculation and based on information that has already been made publicly available.

I am pretty interested to know the release date for Visual Studio 2010, and .NET Framework 4.0, so I asked around but no one could tell me anything. So I decided to do some research as to the release dates for Visual Studio 2005 and Visual Studio 2008 based on the release of their Beta releases. I came up with the following table.

 

Beta 1

Beta 2

RTM

Beta 1 - Beta 2

Beta 2 - RTM

Visual Studio 2005

06/29/2004

04/18/2005

11/07/2005

43 Weeks

29 Weeks

Visual Studio 2008

04/19/2007

07/26/2007

11/19/2007

14 Weeks

17 Weeks

Visual Studio 2010

05/18/2009

11/30/2009

05/09/2010

28 Weeks

20 Weeks

Yellow cells are 100% based just on the averages of the two previous versions

 

When Visual Studio 2005 came out there were huge changes. I think this is why the amount of time between Beta 1 and Beta 2, and between Beta 2 and RTM were so much longer then their corresponding periods in Visual Studio 2008. I think for the release of Visual Studio 2010 we are going to be somewhere between the two time periods. So maybe a decent indicator would simply be the average of the two. This is what I used to come up with the cells that are shaded in yellow. I'm sure this will be off but hopefully by weeks and not months!

   

Sayed Ibrahim Hashimi

msbuild | Visual Studio | Visual Studio 2008 Tuesday, May 26, 2009 4:24:49 AM (GMT Daylight Time, UTC+01:00)  #     | 
Monday, May 18, 2009

ASP.NET MVC: Validation Error ‘A value is required.’

If you are using the ASP.NET MVC DefaultModelBinder to manage the creating complex types from your views’ form data, as well as the validation summary helper provided with ASP.NET MVC then you may have run into the situation I did. I created a simple form, in a dummy app,  to create a new contact. The page is named AddContactClassic.aspx, the contents are shown below.

<% @ Page Title ="" Language ="C#" MasterPageFile ="~/Views/Shared/Site.Master" Inherits ="System.Web.Mvc.ViewPage" %>

 

<% @ Import Namespace ="Sedodream.Web.Common.Contact" %>

 

< asp : Content ID ="Content1" ContentPlaceHolderID ="TitleContent" runat ="server">

      Add Contact Classic

</ asp : Content >

 

< asp : Content ID ="Content2" ContentPlaceHolderID ="MainContent" runat ="server">

    < h2 > Add Contact Classic </ h2 >

   

    <% = Html.ValidationSummary( "Errors exist" ) %>

   

    < ol >< li >< span class ="success-message"> <% = ViewData[ "SuccessMessage" ]%> </ span ></ li ></ ol >

    <% using (Html.BeginForm())

       { %>

    < fieldset >

        < legend > Account Information </ legend >

        < ol >

            < li >

                < label for ="FirstName"> First name </ label >

                <% = Html.TextBox( "FirstName" ) %>

                <% = Html.ValidationMessage( "FirstName" , "*" ) %>

            </ li >

            < li >

                < label for ="LastName"> Last name </ label >

                <% = Html.TextBox( "LastName" ) %>

                <% = Html.ValidationMessage( "LastName" , "*" ) %>

            </ li >

            < li >

                < label for ="Email"> Email </ label >

                <% = Html.TextBox( "Email" )%>

                <% = Html.ValidationMessage( "Email" , "*" )%>

            </ li >

            < li >

                < label for ="Phone"> Phone </ label >

                <% = Html.TextBox( "Phone" )%>

                <% = Html.ValidationMessage( "Phone" , "*" )%>

            </ li >

            < li >

                < div class ="option-group" id ="Gender">

                    <% = Html.RadioButton( "Gender" , Gender .Male.ToString())%> < span > <% = Gender .Male.ToString() %> </ span >

                    <% = Html.RadioButton( "Gender" , Gender .Female.ToString())%> < span > <% = Gender .Female.ToString() %> </ span >

                </ div >

            </ li >            

            < li >

                < input type ="submit" value ="Add contact" />

            </ li >

        </ ol >

    </ fieldset >

    <% } %>

 

</ asp : Content >

In my ContactController class the following methods are defined.

public ActionResult AddContactClassic()

{

    return View();

}

[ AcceptVerbs ( HttpVerbs .Post)]

public ActionResult AddContactClassic( Contact contact)

{

    if (contact == null ) { throw new ArgumentNullException ( "contact" ); }

 

    InternalAddContact(contact);

 

    return View();

}

When I ran the app and filled in all the values on the AddContactClassic page I was a bit surprised to see an error simply stating “A value is required.” Here is a screen shot.

So I assumed that I must have misspelled one of the names of the fields that were passed to the Html.TextBox method. Obviously this was not the issue, so then I remembered that the Contact class that I defined had another property, Id, which I was not contained in a field on the form. This is the case because this page is supposed to create a new Contact, so its Id will not be set. I changed the AddContactClassic(Contact) method to ignore the Id property when binding was occurring. Here is the new method.

[ AcceptVerbs ( HttpVerbs .Post)]

public ActionResult AddContactClassic( [ Bind (Exclude= "Id" )] Contact contact)

{

    if (contact == null ) { throw new ArgumentNullException ( "contact" ); }

 

    InternalAddContact(contact);

 

    return View();

}

By using the Bind attribute I was able to let the DefaultModelBinder know that I was not interested in getting the value for that field. Once I made this change everything worked fine.

In the Contact class I had incorrectly defined the Id property to be Guid instead of Guid? which is better. If I had correctly declared that then the DefaultModelBinder   would have known that it was not a required field and it would not have complained. But if you are using the Entity Framework , you may still have this issue anyway because it does not always create nullable fields for all nullable columns in my experience. Even after changing the Contact class to use Guid? I have purposefully left the Bind(Exclude=”Id”) on the method in case something changes in the implementation of the Contact class.

Sayed Ibrahim Hashimi

Monday, May 18, 2009 4:25:27 AM (GMT Daylight Time, UTC+01:00)  #     | 

ASP.NET MVC: Validation Error ‘A value is required.’

If you are using the ASP.NET MVC DefaultModelBinder to manage the creating complex types from your views' form data, as well as the validation summary helper provided with ASP.NET MVC then you may have run into the situation I did. I created a simple form, in a dummy app, to create a new contact. The page is named AddContactClassic.aspx, the contents are shown below.

<% @ Page Title ="" Language ="C#" MasterPageFile ="~/Views/Shared/Site.Master" Inherits ="System.Web.Mvc.ViewPage" %>

 

<% @ Import Namespace ="Sedodream.Web.Common.Contact" %>

 

< asp : Content ID ="Content1" ContentPlaceHolderID ="TitleContent" runat ="server">

      Add Contact Classic

</ asp : Content >

 

< asp : Content ID ="Content2" ContentPlaceHolderID ="MainContent" runat ="server">

    < h2 > Add Contact Classic </ h2 >

   

    <% = Html.ValidationSummary( "Errors exist" ) %>

   

    < ol >< li >< span class ="success-message"> <% = ViewData[ "SuccessMessage" ]%> </ span ></ li ></ ol >

    <% using (Html.BeginForm())

       { %>

    < fieldset >

        < legend > Account Information </ legend >

        < ol >

            < li >

                < label for ="FirstName"> First name </ label >

                <% = Html.TextBox( "FirstName" ) %>

                <% = Html.ValidationMessage( "FirstName" , "*" ) %>

            </ li >

            < li >

                < label for ="LastName"> Last name </ label >

                <% = Html.TextBox( "LastName" ) %>

                <% = Html.ValidationMessage( "LastName" , "*" ) %>

            </ li >

            < li >

                < label for ="Email"> Email </ label >

                <% = Html.TextBox( "Email" )%>

                <% = Html.ValidationMessage( "Email" , "*" )%>

            </ li >

            < li >

                < label for ="Phone"> Phone </ label >

                <% = Html.TextBox( "Phone" )%>

                <% = Html.ValidationMessage( "Phone" , "*" )%>

            </ li >

            < li >

                < div class ="option-group" id ="Gender">

                    <% = Html.RadioButton( "Gender" , Gender .Male.ToString())%> < span > <% = Gender .Male.ToString() %> </ span >

                    <% = Html.RadioButton( "Gender" , Gender .Female.ToString())%> < span > <% = Gender .Female.ToString() %> </ span >

                </ div >

            </ li >            

            < li >

                < input type ="submit" value ="Add contact" />

            </ li >

        </ ol >

    </ fieldset >

    <% } %>

 

</ asp : Content >

In my ContactController class the following methods are defined.

public ActionResult AddContactClassic()

{

    return View();

}

[ AcceptVerbs ( HttpVerbs .Post)]

public ActionResult AddContactClassic( Contact contact)

{

    if (contact == null ) { throw new ArgumentNullException ( "contact" ); }

 

    InternalAddContact(contact);

 

    return View();

}

When I ran the app and filled in all the values on the AddContactClassic page I was a bit surprised to see an error simply stating "A value is required." Here is a screen shot.

So I assumed that I must have misspelled one of the names of the fields that were passed to the Html.TextBox method. Obviously this was not the issue, so then I remembered that the Contact class that I defined had another property, Id, which I was not contained in a field on the form. This is the case because this page is supposed to create a new Contact, so its Id will not be set. I changed the AddContactClassic(Contact) method to ignore the Id property when binding was occurring. Here is the new method.

[ AcceptVerbs ( HttpVerbs .Post)]

public ActionResult AddContactClassic( [ Bind (Exclude= "Id" )] Contact contact)

{

    if (contact == null ) { throw new ArgumentNullException ( "contact" ); }

 

    InternalAddContact(contact);

 

    return View();

}

By using the Bind attribute I was able to let the DefaultModelBinder know that I was not interested in getting the value for that field. Once I made this change everything worked fine.

In the Contact class I had incorrectly defined the Id property to be Guid instead of Guid? which is better. If I had correctly declared that then the DefaultModelBinder would have known that it was not a required field and it would not have complained. But if you are using the Entity Framework, you may still have this issue anyway because it does not always create nullable fields for all nullable columns in my experience. Even after changing the Contact class to use Guid? I have purposefully left the Bind(Exclude="Id") on the method in case something changes in the implementation of the Contact class.

Sayed Ibrahim Hashimi

ASP.NET MVC Monday, May 18, 2009 4:24:19 AM (GMT Daylight Time, UTC+01:00)  #     | 
Thursday, May 14, 2009

MSBuild: Item & Property Evaluation

A little while ago I received an email from a reader in which he provided a sample MSBuild script. Here were some comments that I sent him.

“One thing that I did notice that may be problematic in your MyBranchTool.common.targets is the following item group.

<ItemGroup>

    <MyTargetFiles Include="$(ProjectDir)$(OutDir)*" />

</ItemGroup>

Here you are declaring an item (outside of a target) which pickups files inside the OutDir. This may include files that were created (or moved there) during the build process.Items and properties declared outside of targets are evaluated before any target executes. What this means is that your MyTargetFiles item may not include all the files that it should. Instead you should put this decclaration inside of a target right before it is needed (which should be after the files have been placed inside the OutDir folder). Unless you are intentionally wanting to pick up the files in that folder before the build starts. If you have my book there is a section on Property & Item Evaluation take a look at that. I think it is somewhere near page 60 or so.”

Also if you are using MSBuild 3.5 you should specify the ToolsVersion on the Project element.”

Here is his response

“Ah, yes thanks for that! I was getting errors sometimes and I thought it was something like that but I didn’t know how to fix it - some files would be deleted by the Rebuild but not recreated, and then the Copy fails because those files are missing.

I have ordered your book, hopefully it arrives soon :) I look forward to reading through it!

Thanks again”

His initial question was not related to the issue that I commented on here. This happened to surface because he sent me his build script. I didn’t have the script that actually used that item, but I recognized that an item was being created from the $(OutDir) in a static item, which is a red flag for a problem ! Like I stated to him since files are placed into the OutDir folder at build time the item should be dynamic and not static. You should look for this in your build scripts as you edit them and make sure that they do not repeat this.

 

Sayed Ibrahim Hashimi

msbuild Thursday, May 14, 2009 3:59:35 AM (GMT Daylight Time, UTC+01:00)  #     |