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


Comment Section

Comments are closed.


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


Comment Section

Comments are closed.


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


Comment Section

Comments are closed.


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.

   

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


Comment Section

Comments are closed.


With MSBuild 3.5 two new known metadata names were introduced for items passed to the MSBuild Task. Those known metadata names are Properties and AdditionalProperties. The idea is that you can now specify properties on the item itself instead of having to pass all the properties using the Properties attribute on the MSBuild Task. For example you could define an item, Projects, to be:

<ItemGroup>

    <Projects Include="Project01.proj">

        <Properties>Configuration=ReleaseProperties>

    Projects>

ItemGroup>
Then you can build the values contained in the Projects item using the MSBuild task:

<Target Name="BuildProjects">

    <MSBuild Projects="@(Projects)"/>

Target>

 

Like I said previously there are two new ways to pass properties in item metadata, Properties and AdditionalProperties. The difference can be confusing and very problematic if used incorrectly. Admittedly I didn't know the difference until about 6 months ago (but soon enough to include in my book J ). The difference is that if you specify properties using the Properties metadata then any properties defined using the Properties attribute on the MSBuild Task will be ignored. In contrast to that if you use the AdditionalProperties metadata then both values will be used, with a preference going to the AdditionalProperties values.

Now let's take a look at an example to make this clear. The following MSBuild file is named Properties.proj and is shown below.

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">

 

<PropertyGroup>

    <ProjectPath>Project01.projProjectPath>

PropertyGroup>

 

<ItemGroup>

     <_ProjectToBuild_Properties Include="$(ProjectPath)">

         <Properties>Configuration=DebugProperties>

    _ProjectToBuild_Properties>

ItemGroup>

<ItemGroup>

    <_ProjectToBuild_AdditionalProperties Include="$(ProjectPath)">

        <AdditionalProperties>Configuration=DebugAdditionalProperties>

    _ProjectToBuild_AdditionalProperties>

ItemGroup>

 

<Target Name="Build_Properties">

    <Message Text="Building project with Properties metadata" Importance="high"/>

    <MSBuild Projects="@(_ProjectToBuild_Properties)" Properties="DebugSymbols=true" />

Target>

 

<Target Name="Build_AProperties">

    <Message Text="Building project with AdditionalProperties metadata" Importance="high"/>

    <MSBuild Projects="@(_ProjectToBuild_AdditionalProperties)" Properties="DebugSymbols=true" />

Target>

 

Project>

I've highlighted a few important elements contained in this file. Firstly if you do not specify your ToolsVersion to be 3.5 then none of this functionality will work. Make sure to always provide this value, or you may be baffled by the un-expected behavior.

Inside of both targets you can see that I and providing the value Properties="DebugSymbols=true". Below is the definition of the file that it is building, the Project01.proj file.

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">

 

<Target Name="Build">

    <Message Text="Building $(MSBuildProjectFile)" Importance="high"/>

    <Message Text="Configuration: $(Configuration)"/>

    <Message Text="DebugSymbols: $(DebugSymbols)"/>

    <Message Text="OutputPath: $(OutputPath)"/>

Target>

 

Project>

This file just prints out the values for a couple of properties that are not defined inside the file itself. Now let's see the behavior when we execute both of these targets. The result is shown in the image below.

As I've highlighted here the result of executing the Build_Properties target results in the attribute Properties="DebugSymbols=true" being completely ignored. The result from the Build_AProperties target takes the Properties attribute into consideration as well as the AdditionalProperties metadata. Don't use both of these together!

I personally prefer using the AdditionalProperties because I think that ignoring the Properties attribute can be confusing and hard to diagnose. This is why I tend to use that approach instead of the Properties metadata unless I have a specific reason.

Sayed Ibrahim Hashimi

 

 

 


Comment Section

Comments are closed.


<< Older Posts | Newer Posts >>