David Williams

Who's sruffy looking?

  Home  |   Contact  |   Syndication    |   Login
  19 Posts | 0 Stories | 16 Comments | 0 Trackbacks

News



Twitter












Archives

Post Categories

Microsoft Development

Thursday, November 11, 2010 #

Recently we upgraded one of our solutions from Visual Studio 2008 to Visual Studio 2010.  After checking in our code to our 2008 Team Foundation Server, the CI build unexpectedly failed.  We were getting errors like:

c:\build\MyApplication\MyApplication.csproj(89,3): error MSB4019: The imported project "C:\Program Files\MSBuild\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" was not found. Confirm that the path in the <Import> declaration is correct, and that the file exists on disk.

After a bit of Googling, I did the following:

  1. Install .Net framework 4.0 on build server (http://www.richard-banks.org/2009/11/how-to-build-vs2010-solutions-using.html).
  2. Modified the TFSBuildService.exe.config file at C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\PrivateAssemblies to use the 4.0 framework for building.  I changed the MSBuildPath key to C:\[WINDOWS\Microsoft.NET\Framework\v4.0.30319.
  3. Restart Build Service.
  4. Install Visual Studio 2010 on the Build server.

This seemed to help, however I received another error related to TFS workspaces:

C:\Program Files\MSBuild\Microsoft\VisualStudio\TeamBuild\Microsoft.TeamFoundation.Build.targets(801,5,801,5): error : The path c:\controlsite\nightly is already mapped in workspace TFSSERVER_83. [C:\BuildWorking\Muzak Control Site\Control Site Nightly Build\BuildType\TFSBuild.proj]

I used the Team Foundation Server Sidekick to remove the conflicting workspaces.  The builds then ran fine.

I referenced the following:

Richard Banks - How To Build VS2010 Solutions Using TFS2008 Team Build

Building Visual Studio 2010 solutions using Team Build 2008

  • Share This Post:
  • Share on Twitter
  • Share on Facebook
  • Share on Technorati

Tuesday, October 26, 2010 #

For those who said they were praying for Amy, and little more detail is in order.  Amy has a mild form of narcolepsy.  Officially she is diagnosed as “Idiopathic Sleepiness”, however it amounts to the same thing.  Ever since she was pregnant, she has not been able to take stimulants to help her stay awake.  As a result, she is much more tired than usual, and has particular trouble taking the kids places.  If you know Amy you know she is very active-very type “A” personality, so as you can imagine this is very frustrating to her.  Please pray the Lord gives her strength, alertness and sustains her during the day.  Thanks,

David

  • Share This Post:
  • Share on Twitter
  • Share on Facebook
  • Share on Technorati

Thursday, October 21, 2010 #

Before working with MVC, I would claim to be somewhat intimidated by JavaScript development.  Not that I did not know how to use it, however I found that is was much more bug prone and harder to develop against.  Having the .Net compiler was a nice safety net-I did not have to worry about variable name mismatch, typos, not to mention the .Net framework itself.  In a recent ASP.Net project we used the MS AJAX update panel to implement interface changes that could easily be implemented via client side JavaScript.  For example a ‘select all’ link to select multiple checkboxes was implemented as a button click event in the code behind with an update panel.  Certainly not the best way to do this, but the thought was to let the Code-behind do the heavy lifting. 

With the advent of AJAX(Web 2.0), MVC, and JQuery, it is no longer a viable option to attempt implement all interface functionality on the server.  I believe the expectation of users has changed with relation to page life-cycle and page post backs.  Consider Facebook, Google or most of the prominent websites. 

Fortunately in MVC and other prevalent technologies, I no longer fear JavaScript as much as I used to.  Certain changes make JavaScript development much more of a pleasant experience:

  1. JQuery just makes JavaScript development x10.  For example with JQuery you can do many thing in one line of code: display a dialog, replace the contents of a div tag from a server side method
  2. JQuery greatly simplifies JavaScript in several ways, including cross browser compatibility.  There is no longer any need to write customizations for different browsers.
  3. Better debugging support in browsers including IE7+, as well as Visual Studio.  (I usually use IE’s debugging, it is easier to use.
  4. Utilizing MVC allows easier querying of DOM elements.  Ids like ‘ctl00_pagebody_ucLocalDashboard_tcTabby_tpSetups_ddlPageSize’ are no longer used.
  • Share This Post:
  • Share on Twitter
  • Share on Facebook
  • Share on Technorati

Monday, October 18, 2010 #

Sometimes it seems implementing functionality in ‘standard’ asp.net takes several times longer than with MVC.  In my case, I wanted to do the following when changing a checkbox on a form page (page uses partial page update).  Note that I needed to use both client side and server side functionality, and the page updates only part of the page.

  1. On checkbox changed, display an “are you sure” popupup.
  2. On ‘Ok’, call server method to modify data on the backend, re-bind part of the page.
  3. On ‘Cancel’, close popup, set the checkbox to the value before the popup was displayed.
  4. Implement using partial page update (update panel/partial view with AJAX).

‘Standard’ ASP.Net Implementation

This seems to me to be a simple task.  However to make this work in ‘standard’ ASP.Net, I had to do the following:

  1. Create a checkbox with a onClick method (CheckboxChanged). (Did not use AutoPostBack=True or OnCheckChanged client event.)
    1. OnClick JS function uses “$find('modalPopupApps').show();” to
  2. Create Hidden div with modal popup content and a ModalPopupExtender.
    1. Point TargetControlID to meaningless control (lblHello). 
    2. Add BehaviorID ("modalPopup”)
  3. Add Hidden asp button (display:none), create server side event for button.
  4. In modal popup div, Add input button for “Ok”.  Onclick call JS function (ChangeOk) to call server method. 
    1. (Could not get asp.net button to work, likely related to update panel)
    2. ChangeOk uses “document.getElementById('<%= btnHiddenApps.ClientID %>').click(); “ to call hidden buttons onClick server side event.
    3. Server side event handles business logic, hides popup (modalPopup.hide();), re-binds data controls.
    4. (Verify/debug server side events to verify method is bound to event correctly.)
  5. In modal popup div, Add input button for “Cancel”.  Onclick call JS method (ChangeCancel)
    1. Could not use asp.net button.  Remove CancelControlID.
    2. JS function uses $find('modalPopupApps').hide();

I sort of hope I missed something basic here, this seems like an awful lot of work.  No doubt there are many other ways to implement this, likely many better methods.  If anyone can see something I missed please let me know (but please be kind).  (Glancing at the rest of the application, I see some pages move the hidden button outside of the update panel.)  However I spent several hours on this before going with this solution.  For context I should add that I consider myself to have a good set of ASP.Net/MS Ajax experience under my belt (although you may find that hard to believe after seeing the above).  Regardless, this shows how complex Asp.net ‘standard’ with MS AJAX can get, or at the least that it can be less than clear how to implement client side functionality.

ASP.Net MVC/JQuery implementation

In comparison with MVC using JQuery, to implement I would do the following:

  1. Add a hidden div (display:none).
  2. On document.ready, declare a dialog using JQuery “.dialog”, link to the hidden div
    1. In the declaration, bind “Ok” to ChangeOk method.
    2. In the declaration, us JQ to find Checkbox, not checked value, close dialog ($(this).dialog('close');)
  3. In ChangeOk:
    1. Use (magical) JQuery to call an MVC ActionMethod to modify data on backend and return partial view.  Much of this can be refactored for reusability/readability.
      - ($(‘div’).load(“/Page/Partial”, fuction(html){$(“partialDiv”)[0].value = html}))
    2. Close the dialog (.dialog('close')).
  4. Create a checkbox, add onclick=”$("#hiddenDiv").dialog('open');”

To me it seems the MVC solution is much simpler and easy to understand, with fewer gotchas and moving parts. 

  • Share This Post:
  • Share on Twitter
  • Share on Facebook
  • Share on Technorati

Thursday, October 14, 2010 #

At a high level, this is how I understand the different MVC tiers:

  • Model: Data libraries such as entities, Linq to SQL classes, or any other data library.
  • View: The .aspx/.ascx pages.  The classic ASP style code goes here.  I have heard this layer referred to as a ‘report’ where you have as little logic as possible, and only that related to the display of the page. 
  • Controller:  If you are coming from ‘standard’ ASP.Net and are new to MVC, You could say the controller is what replaces the code behind.  However the controller is very different.  Think of a controller as code that packages data to send to View.  It has no events, no viewstate, but a series of actions or methods that return data to the View.
  • “View Model”:  Think of a ViewModel as having only the data that is needed by the View.  Typically the controller takes data from (for example) one or more Models, and places it in the ViewModel.  Not all data from the Model makes it into the view, and the controller can add additional info not in the Model. 
  • Share This Post:
  • Share on Twitter
  • Share on Facebook
  • Share on Technorati

Someone asked me the other day, between Standard ASP.Net and ASP.Net MVC, which do I prefer and why.  Although I have long been an ASP.Net developer, I have to say that I easily would choose MVC over standard ASP.net any day (and twice on Sunday).   I feel this for the following reasons:

  • Separation of interests: The three sections of MVC are logically separated: Model(Data), View(.aspx page), Controller (Code that feeds data to view). 
  • NO VIEWSTATE:  If you are new to MVC, you think this is a bad thing, but it is actually very, very good.
  • Performance: Because there is no viewstate, there is no decoding/encoding of viewstate, no unneeded data passed back and forth to the browser.
  • MVC is more AJAX/JavaScript friendly.  For example:  No more funky control names like ‘ctl00_pagebody_ucSetupList_gvSetups_ctl02_hlSetupName’.
  • Easier to test.  Separation of interests allows you to test the controller methods directly.
  • No events.  Like ViewState, if you are new to MVC, you think this is bad.  Actually this too is very very good.
  • Did I say NO VIEWSTATE?  Yes, but it bears repeating.

Personally I am in love with MVC and no longer enjoy working on any of my legacy ‘standard’ ASP.Net sites.

  • Share This Post:
  • Share on Twitter
  • Share on Facebook
  • Share on Technorati

Tuesday, October 20, 2009 #

I have often attempted to find TFS build properties that can be used in build scripts.  This seems to be difficult to find via Google, so I am documenting this here.
1. Aaron Hallberg has an entry listing the Team Build 2008 properties.
2. MSDN lists a few TFS Build properties, a few of which are not listed in above. Customizable Team Foundation Build Properties

  • Share This Post:
  • Share on Twitter
  • Share on Facebook
  • Share on Technorati

Tuesday, March 03, 2009 #

One of the things I enjoy about a subscription to MSDN is access to all of the latest versions software.  So when Installing Office 2007 some time ago, I installed OneNote as well.  I did not get the point of this application at first, however I have found OneNote to be a useful tool for keeping track of my To Do items, as well creating a detailed list of Items for a specific project I am working on.  

image

 

What I find especially useful is the ability to create cascading to do items.  Outlook provides a task list, but there is no way to create sub items.

In addition to an overall to do list, I use it to as my notebook for any applications I am working on, server information and passwords, and any general information I want to keep track of. 

  • Share This Post:
  • Share on Twitter
  • Share on Facebook
  • Share on Technorati

Monday, March 02, 2009 #

Update: This can be accomplished with the MsBuild Extension Pack using the MsBuild.ExtensionPack.TFS.DevEnv

Team Build is great for building Projects applications such as Windows or Web apps.  However it is not able to build Install packages.  Because of this you have to use the Visual Studio build command line option, and copy the .msi and setup.exe files out of the local build directory.  My builds usually copy the built files from to a stage or production server, However this is difficult to do, as no TB/MSbuild variables correctly reference the local build location.  To build a visual studio setup project, I did the following:

  1. Enable building in the Solution configuration manager.  Select the configuration manger, checked build next to the Install project name. 
  2. Open the ApplicationSetup.proj file in a text editor. Searching for ProjectOutput, SourcePath, I confirmed the path was relative to the project file (..\\obj\\Release\\HelloWorld.exe) rather then literal (C:\HelloWorld\obj\\Release\\HelloWorld.exe).
  3. Modified the Build project, adding the build target type

    <Target Name="AfterCompile">

        <Exec Command=
        "&quot;$(ProgramFiles)\Microsoft Visual Studio 9.0\Common7\IDE\devenv&quot;
        &quot;$(BuildDirectory)\HelloWorld\HelloWorldInstall\HelloWorldSetup.vdproj&quot;
        /Build
    &quot;Release|Any CPU&quot;"/>
    </Target>

  4. Created a target to copy the files.  Unfortunately, the built executables are not copied to the drop location.  Their is no TFS build variable that represents the build location.  To copy the files, I had to use a literal path to the build location.  The files were referenced as "C:\build\HWBuildLoc\..." instead of $(SolutionRoot). The MSDN documentation suggests using $(SolutionRoot) to get the local build location, however this returns the incorrect directory. 

    <Target Name="AfterDropBuild">

        <Time Format="yyyyMMdd_HHmmss">

            <Output TaskParameter="FormattedTime" PropertyName="BuildDate" />

        </Time>

     

        <!-- Copy files to Stage -->

        <CreateItem Include="\\StageServer\HelloWorld_$(BuildDate)">

            <Output PropertyName="BuiltProjectStagePath"
           
    TaskParameter="Include" />

        </CreateItem>

     

       

     

        <CreateItem Include=
           
    "C:\build\HWBuildLoc\HelloWorld\HelloWorldInstall\Release\**\*.*" >

            <Output ItemName="FilesToCopy" TaskParameter="Include" />

        </CreateItem>

        <!-- Copy installer -->

        <Copy SourceFiles="@(FilesToCopy)"

             DestinationFiles=
             "@(FilesToCopy ->'\\StageServer\StageDirecoty\%(RecursiveDir)%(Filename)%(Extension)')"

             ContinueOnError="true"/>

    </Target>

  5. This does cause the application to be built twice: once through the normal build process, and again by the visual studio command line call. 

I referenced the following:

  1. Team Build target map
  2. Team Build Property Reference by Aaron Hallberg
  3. Walkthrough: Configuring Team Build to Build a Visual Studio Setup Project
  • Share This Post:
  • Share on Twitter
  • Share on Facebook
  • Share on Technorati

Friday, September 05, 2008 #

If you have ever used Beyond Compare from Scooter software, I don't have to tell you this is a great directory/file comparison tool, especially for the price (Single licenses are listed at $30).  If you don't use this tool, I highly recommend you take the time to download a copy and kick the tires for the 30 day trial.  As I recall with version 2, the trial period lasted for 30 usage days, not 30 days from install.  I don't know if the same applies for version 3. 

The comparison is far better than the comparison that comes out of the box with Visual Studio 2005/2008 and/or Team Foundation Server.  However to set it up you have to follow a few configuration steps.  These are well documented by Marc Brooks at this entry (Beyond Compare 2), and in more detail by James Manning (Beyond Compare 2 & 3). 

  • Share This Post:
  • Share on Twitter
  • Share on Facebook
  • Share on Technorati

Thursday, September 04, 2008 #

The other night at our local development group, the Charlotte based Enterprise Developers Guild, Brian Hitney from Microsoft gave and Overview of Microsoft ASP.NET MVC.  This is my first time seeing the MVC pattern from Microsoft.  This is the take away Items from this talk which may be helpful to those that are new to the MVC concept. 

Routing

Before discussing the structure of the MVC pattern, it is important to understand how pages are routed through the MVC.  Using a Routing table, links are directed to pages in the following manner:

  • www.Website.com\home\ - goes to homepage
  • www.Website.com\home\data - routes to data page
  • www.Website.com\home\data\14 - routes to data page with index of 14
  • www.Website.com\home\date\edit\14 - I am not certain about this one, but I believe this (or something similar) could be used to route to the data page, edit method with for item 14.  For this to work, the necessary edit method would have to be implemented in the date controller class. 

The basic concept  of the MVC though is the separation of system logic into three separate pieces:

Model

Represented the Data.  In the example the other night, Brian mapped a set of relationships from a database using LINQ/DBML.  In this simple case no other work was done to create the data objects/object models.  As I understand this could also be done using technologies such as NHibernate. 

Controller

This class is where the coding logic for the page goes.  For lack of a better term, this page handles page events (although let me be clear, there are no events in the traditional sense in MVC).  This class would contain methods such as Edit, View, Index etc.  To display individual items, the Data that is generated is sent to the View page.

View

The actual pages that displays the data sent to it from the Control View.  A number of interesting items stood out to me:

  • There is no concept of Page postback in the MVC pattern.  For that reason no page events are handled and processed on the View page. 
  • No ViewState on the page, as the page never posts back to itself.  Because of this the pages are very lightweight.  This also means there is no event processing, and no ability to retrieve Control Data as you would a typical page. 
  • No code behind: The display of items on the Page itself was bound using some classic ASP type syntax.  Rather than using code behind to bind (for example) GridView Items, Items were bound using inline syntax such as <%=Html.TextBox("ProductName")%) or even <%# Eval("ProductName") %>.  This feels like a step backward, but In the end this produces simpler and more lightweight code.  

In the end this model is very different from the traditional ASP.Net model, produces very lightweight HTML, and because of the separation of logic lends itself very well to testing.  On the other hand Brian mention that 90% of Asp.Net web applications in the future are not likely to use this approach. 

Obviously I am only scratching the surface of MVC.  I hope I have accurately described what I have described though.  Of course many more examples can be found as Scott Guthrie's Blog

  • Share This Post:
  • Share on Twitter
  • Share on Facebook
  • Share on Technorati

Recently I needed to create a CustomValidator inside a GridView.  In the end this was relatively straight forward, however I had some problems in my main application.  As I could not find any examples of this on the Internet, I am documenting this here. 

As a proof of concept I created a web page with an UpdatePanel containing a ValidationSummary, a simple GridView and a button.  The GridView was populated by an XMLDataSource (for simplicity), and a column template containing two text boxes and a custom validator.  The Custom validator was validated via code on the server side.  The validation summary correctly displayed all error messages.  I found the following:

  • I did have to set the CustomValidators ValidateEmptyText=True, However ControlToValidate did not have to be set.  This was important as control visibility changed based on the data items.
  • In the CustomValidator_ServerValidate function, I was able to use CustomValidator.NamingContainer to get the Containing GridView Row.  From there I was able to get all of the controls on that row.
  • I did not have to do any binding in the GridView databound event to make this work. For example I did not have to bind the Custom Validator to the ControlToValidate using the Contols ClientID.  I saw talk on some forums about binding the custom validator when building the GridView.
  • The UpdatePanel did not make a difference.

Here is the Code:

 

 

<asp:ScriptManager ID="ScriptManager1" runat="server" />

<asp:UpdatePanel ID="UpdatePanel1" runat="server">

    <ContentTemplate>

        <div>

            <asp:ValidationSummary ID="ValidationSummary1" runat="server" />

        </div>

        <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"

                DataSourceID="XmlDataSource1">

            <Columns>

                <asp:BoundField DataField="Name" HeaderText="Name" SortExpression="Name" />

                <asp:TemplateField HeaderText="Validation Test">

                    <ItemTemplate>

                        1:<asp:TextBox ID="TextBox1" runat="server"

                           Visible='<%# Eval("Enter1") %>'></asp:TextBox>

                        &nbsp;2:<asp:TextBox ID="TextBox2" runat="server"

                            Visible='<%# Eval("Enter2") %>' ></asp:TextBox>

                        <asp:CustomValidator ID="CustomValidator1" runat="server"

                            ErrorMessage="CustomValidator" Text="*"

                            onservervalidate="CustomValidator1_ServerValidate"

                            ValidateEmptyText="True"></asp:CustomValidator>

                    </ItemTemplate>

                </asp:TemplateField>

            </Columns>

        </asp:GridView>

        <asp:Button ID="Button1" runat="server" Text="Submit" />

    </ContentTemplate>

</asp:UpdatePanel>

<asp:XmlDataSource ID="XmlDataSource1" runat="server" DataFile="~/XMLFile1.xml">

</asp:XmlDataSource>

 

Partial Public Class _Default : Inherits System.Web.UI.Page

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

    End Sub

 

    Protected Sub CustomValidator1_ServerValidate(ByVal source As Object, _

             ByVal args As System.Web.UI.WebControls.ServerValidateEventArgs)

        Dim cv As CustomValidator = CType(source, CustomValidator)

        Dim gvr As GridViewRow = cv.NamingContainer

        Dim txt1 As TextBox = gvr.FindControl("TextBox1")

        Dim txt2 As TextBox = gvr.FindControl("TextBox2")

 

        'If String.IsNullOrEmpty(txt1.Text) Or String.IsNullOrEmpty(txt2.Text) Then

        If (txt1.Visible And String.IsNullOrEmpty(txt1.Text)) Or _

                (txt2.Visible And String.IsNullOrEmpty(txt2.Text)) Then

            cv.ErrorMessage = String.Format("Please enter text on row {0}", gvr.RowIndex)

            args.IsValid = False

        End If

    End Sub

End Class

 

<?xml version="1.0" encoding="utf-8" ?>

<customers>

    <customer Id="1" Enter1="true" Enter2="true"/>

    <customer Id="2" Enter1="true" Enter2="false"/>

    <customer Id="3" Enter1="false" Enter2="true"/>

    <customer Id="4" Enter1="false" Enter2="false"/>

</customers>

 

 

 

  • Share This Post:
  • Share on Twitter
  • Share on Facebook
  • Share on Technorati

Monday, August 11, 2008 #

One thing about the Visual Studio interface has often bothered me:  There is not a very good way to bookmark code - by that I mean the "bookmark" feature does not work very well.  Although I am able to set and clear bookmarks using the bookmarks toolbar in code, it does not highlight code in editor like Breakpoints do.  For that reason, I usually use breakpoints when working my way through code, and I wonder how many developers do the same.

Visual Studio Bookmarks

The VS Options Interface gives you the option to change the Fonts/Colors of the bookmarks by changing the background color of the custom text.  However in order to get this to work you have to remove disable the Indicator margin as explained in How to change a bookmark color?.  Although this is better this results in not being able to add and remove break points as easily. 

image 

By default (at least as my keyboard is setup) to set a breakpoint in this mode you have to use a function key (F9).  Setting and clearing bookmarks using the control keys seem a little awkward as well.  A bookmark is toggled by selecting ctrl-K, but you have to select it twice.  Scrolling between Bookmarks is done by selecting Ctrl-K, Ctrl-P and Ctrl-K, Ctrl-N.

In the big scheme of thing this is minor, but this is one of those items I wish was implemented better. 

  • Share This Post:
  • Share on Twitter
  • Share on Facebook
  • Share on Technorati

Friday, August 08, 2008 #

Recently I attempted to setup an editor to connect to GWB.  Until this post I used MS Word 2007 to post to GWB, as I was unable to get Windows Live Writer to install.  WLW consistently gave the following error when installing:

There was a problem with this installation. Windows Live Suite was not installed. Code: 0x800070643.

clip_image002

I tried a number of steps to resolve this with MS's Help:

  1. Ran the installation outside my firewall, while downloading the executable to disk first. I also stopped my OfficeScan Debugger (as best as I can tell), as well as Windows defender while installing.
  2. Unregistered(("%windir%\system32\msiexec /unregserver") and re-registered(%windir%\system32\msiexec /regserver") Windows Installer.
  3. Ran the Windows Installer Cleanup from here (although now Windows Live components were found).
  4. Installed Windows Live Imaging Component and SQL Server 2005 Compact - (Actually MS recommended those two steps, I am not certain why)
  5. Finally the step that I suspect worked was to remove some left over registry keys:
    reg query "hklm\software\microsoft\windows live" 
    reg query "hkcu\software\microsoft\windows live" << Listed some entries
    I deleted the entries from the registry using:
    reg delete "hkcu\software\microsoft\windows live"
  6. MS did also provide a link to the actual MSI file but this was not run until step 5 was run.

In the end it took a lot of work to get this installed.  I suspect the culprit was the leftover registry entries.  In any case I am using it now, and I do like it better than MS Word.

  • Share This Post:
  • Share on Twitter
  • Share on Facebook
  • Share on Technorati

It has been I have posted to this blog, and I am hoping a blogging writer (such as Word 2007 or Windows Live Writer) will help me to post more often. Unfortunately although I have seen recommendations for Windows Live writer, I have not been able to install it successfully. Hence this test post through MS Word 2007.

  • Share This Post:
  • Share on Twitter
  • Share on Facebook
  • Share on Technorati