Category Archives: Current Work

Better ASP MVC Select HtmlHelper

As a lot of you who have read stuff I have written about before will know that I am mainly interested in desktop development, WPF in fact. You may have also noticed that my blog has been a bit quite lately, which is due to the fact I am working on a pretty large open source project using ASP MVC 3, which is eating all my spare time, as such I have not been writing as many articles as I had been. The open source project is coming along nicely, and I am getting closer to completing it.

During the course of working on this open source project I have been trying to write ASP MVC 3 code using best practices and have an excellent ASP MVC clued up colleague who answers my dumb questions.

Now the other day I asked him why the standard HtmlHelper.DropDown and HtmlHelper.DropDownFor extension methods require you to use some really filthy objects such as SelectListItem.

Now I don’t know who will be reading this post, but I come from WPF land which kind of paved the way for the ModelViewViewModel  pattern, which ASP MVC seems to borrow for its Model approach these days. I think it is fair to say that most ASP MVC devs will be treating their Models and View specific Models AKA ViewModels.

So we have this Model for the View (AKA ViewModel), which gets bound to a Razor view using ASP MVCs Model Binding (assuming you are using Razor view engine and not just some REST/JSON/JQuery Ajax approach where you miss the view engine out altogether, that’s cool stuff too, but not the subject of this post). Ok so far, but now I want to create a DropDownList (HTML Select tag) using one of the existing HtmlHelper.DropDownList and HtmlHelper.DropDownListFor extension methods. This is where the fun starts, I now have to pollute my nice clean view specific model (ViewModel) with crap which in my opinion, is a view concern.

Ok you could argue that the Model is view specific so what is the harm in having a IEnumerable<SelectList> property in there. Well it just doesn’t sound right to me, and lets push the boat out a bit more, and imagine I want to test my Models. They now have UI Specific stuff in them, so my tests now have to know about UI specific stuff. Which again sounds wrong to me.

Ok I don’t know what your tests look like, but mine have separate test suites for models, than I do for my controller tests. In my test suite where I am testing my controllers I half expect a bit of stuff to do with view specifics such as ViewData, Session, ActionResults etc etc, but in my models I just don’t want any UI stuff in there.

So what can we do about it.

Well the answer is surprisingly simple, we just create our own HtmlHelper which does a better job and allows us to maintain a nice clean model and allows better separation of concerns.

Ok lets have a look at the finished code then shall we. Oh one thing before we start, I am using a standard ASP MVC 3 project that you get when you start a new ASP MVC Razor based project from within Visual Studio 2010, so I hope you are familiar with that and the objects it creates.

The Model

This is dead easy, and just exposes the model data. Notice how I do not have an UI stuff like SelectList in here. Its just standard data. Obviously this will vary for your specific requirements

This is a demo model

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace MvcApplication1.Models
{
    public class Person
    {
        public int Id { get; private set; }
        public string Name { get; private set; }
        public Person(int id, string name)
        {
            this.Id = id;
            this.Name = name;

        }

        public override string ToString()
        {
            return String.Format("Id : {0}, Name : {1}", Id, Name);
        }
    }


    public class PeopleViewModel
    {
        public int SelectedPersonId { get; set; }
        public List<Person> Staff { get; set; }

        public PeopleViewModel()
        {

        }
        
        public PeopleViewModel(int selectedPersonId, List<Person> staff)
        {
            this.SelectedPersonId = selectedPersonId;
            this.Staff = staff;
        }
    }


}

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

 

The HtmlHelper

This is where the real work is done, and I came up with 2 approaches which are both shown below. The attached source code has them both in but only one is active, the other is commented out. I will leave it to the user to decide which they prefer.

However one thing both approaches have in common is that they use Expression<Func<T,Object>> to obtain all the information required to create the html select using the models properties. This can be seen below where I show a demo of it within the demo view.

Option 1 : Defer to the standard HtmlHelper

This option defers to the standard HtmlHelper.DropDownList but this new HtmlHelper creates the SelectList(s) for the standard HtmlHelper.DropDownList

 

using System;
using System.Text; 
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Web.Mvc;
using System.Web.Mvc.Html;
using MvcApplication1.Helpers;

namespace MvcApplication1.MyHelpers
{
    public static class HtmlHelperExtensions
    {
        /// <summary>
        /// Provides a better HtmlHelper dropdown list function
        /// that is type safe and does not fill your model with View specific gunk
        /// </summary>
        /// <typeparam name="TModel">The Model type</typeparam>
        /// <typeparam name="TItem">An item type from the source list</typeparam>
        /// <typeparam name="TValue">A value type for one of the items 
        /// in the source list</typeparam>
        /// <typeparam name="TKey">A text type for one of the items 
        /// in the source list</typeparam>
        /// <param name="htmlHelper">The actual HtmlHelper</param>
        /// <param name="selectedItemExpr">An expression which selects 
        /// the selected item from the model</param>
        /// <param name="enumerableExpr">An expression which selects 
        /// the source list from the model</param>
        /// <param name="valueExpr">An expression that selects a 
        /// value from an item</param>
        /// <param name="keyExpr">An expression that selects text 
        /// value from an item</param>
        /// <param name="htmlAttributes">The Html Attributes to apply 
        /// to the overall select string which gets rendered</param>
        /// <returns>A HTML encoded string, which represents a HTML 
        /// select tag with the attributes provided</returns>
        public static MvcHtmlString ComboFor<TModel, TItem, TValue, TKey>(
            this HtmlHelper<TModel> htmlHelper,
            Expression<Func<TModel, TValue>> selectedItemExpr,
            Expression<Func<TModel, IEnumerable<TItem>>> enumerableExpr,
            Expression<Func<TItem, TValue>> valueExpr,
            Expression<Func<TItem, TKey>> keyExpr,
            IDictionary<string, object> htmlAttributes) where TValue : IComparable
        {
            TModel model = (TModel)htmlHelper.ViewData.Model;

            string id = ExpressionUtils.GetPropertyName(selectedItemExpr);

            TValue selectedItem = selectedItemExpr.Compile()(model);
            IEnumerable<TItem> sourceItems = enumerableExpr.Compile()(model);

            Func<TItem, TKey> keyFunc = keyExpr.Compile();
            Func<TItem, TValue> valueFunc = valueExpr.Compile();

            List<SelectListItem> selectList =
                (from item in sourceItems
                 let itemValue = valueFunc(item)
                 let itemKey = keyFunc(item)
                 select new SelectListItem()
                     {
                         Selected = selectedItem.CompareTo(itemValue) == 0,
                         Text = itemKey.ToString(),
                         Value = itemValue.ToString()
                     }).ToList();

            return htmlHelper.DropDownList(
                   id.ToString(), selectList, htmlAttributes);
        }
    }
}

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

 

Option 2 : Do all the work ourselves

This option means we MUST do everything that a standard HtmlHelper extension method would do, which means taking care of things like “Name” and “Id” for the generated html, and also ensuring its rendering correctly using a html encoded string

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Web.Mvc;
using System.Web.Mvc.Html;
using MvcApplication1.Helpers;
using System.Text;

namespace MvcApplication1.MyHelpers
{
    public static class HtmlHelperExtensions
    {
        /// <summary>
        /// Provides a better HtmlHelper dropdown list function
        /// that is type safe and does not fill your model with View specific gunk
        /// </summary>
        /// <typeparam name="TModel">The Model type</typeparam>
        /// <typeparam name="TItem">An item type from the source list</typeparam>
        /// <typeparam name="TValue">A value type for one of the items 
        /// in the source list</typeparam>
        /// <typeparam name="TKey">A text type for one of the items 
        /// in the source list</typeparam>
        /// <param name="htmlHelper">The actual HtmlHelper</param>
        /// <param name="selectedItemExpr">An expression which selects 
        /// the selected item from the model</param>
        /// <param name="enumerableExpr">An expression which selects 
        /// the source list from the model</param>
        /// <param name="valueExpr">An expression that selects a 
        /// value from an item</param>
        /// <param name="keyExpr">An expression that selects text 
        /// value from an item</param>
        /// <param name="htmlAttributes">The Html Attributes to apply 
        /// to the overall select string which gets rendered</param>
        /// <returns>A HTML encoded string, which represents a HTML 
        /// select tag with the attributes provided</returns>
        public static MvcHtmlString ComboFor<TModel, TItem, TValue, TKey>(
            this HtmlHelper<TModel> htmlHelper,
            Expression<Func<TModel, TValue>> selectedItemExpr,
            Expression<Func<TModel, IEnumerable<TItem>>> enumerableExpr,
            Expression<Func<TItem, TValue>> valueExpr,
            Expression<Func<TItem, TKey>> keyExpr,
            IDictionary<string, object> htmlAttributes) where TValue : IComparable
        {
            TModel model = (TModel)htmlHelper.ViewData.Model;

            string id = ExpressionUtils.GetPropertyName(selectedItemExpr);

            TValue selectedItem = selectedItemExpr.Compile()(model);
            IEnumerable<TItem> sourceItems = enumerableExpr.Compile()(model);

            Func<TItem, TKey> keyFunc = keyExpr.Compile();
            Func<TItem, TValue> valueFunc = valueExpr.Compile();

 

            TagBuilder selectBuilder = new TagBuilder("select");
            selectBuilder.GenerateId(id.ToString());
            selectBuilder.MergeAttribute("name", id, true);
            selectBuilder.MergeAttributes(htmlAttributes, true);

            StringBuilder optionsBuilder = new StringBuilder();

            foreach (TItem item in sourceItems)
            {
                TagBuilder optionBuilder = new TagBuilder("option");
                object itemValue = valueFunc(item);
                object itemKey = keyFunc(item);

                optionBuilder.MergeAttribute("value", itemValue.ToString());
                optionBuilder.SetInnerText(itemKey.ToString());

                if (selectedItem.CompareTo(itemValue) == 0)
                {
                    optionBuilder.MergeAttribute("selected", "selected");
                }
                optionsBuilder.AppendLine(MvcHtmlString.Create(
                    optionBuilder.ToString(TagRenderMode.Normal)).ToString());
            }

            selectBuilder.InnerHtml = optionsBuilder.ToString();

            MvcHtmlString x = MvcHtmlString.Create(
                selectBuilder.ToString(TagRenderMode.Normal).ToString());

            return x;
        }

    }
}

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

This code also makes use of this utility class to grab the name of a property from an Expression
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Linq.Expressions;
using System.Reflection;

namespace MvcApplication1.Helpers
{
    public static class ExpressionUtils
    {

        public static string GetPropertyName<TModel, TItem>(
           Expression<Func<TModel, TItem>> propertyExpression)
        {
            var lambda = propertyExpression as LambdaExpression;
            MemberExpression memberExpression;
            if (lambda.Body is UnaryExpression)
            {
                var unaryExpression = lambda.Body as UnaryExpression;
                memberExpression = unaryExpression.Operand as MemberExpression;
            }
            else
            {
                memberExpression = lambda.Body as MemberExpression;
            }

            var propertyInfo = memberExpression.Member as PropertyInfo;

            return propertyInfo.Name;
        }

    }
}

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

 

A Demo View

This is a small demo view that goes with the model/controller supplied at the bottom of this post. Again you will need to change this depending on your own requirements

Note the “using” at the top of the view which lets us include our new HtmlHelper extension method

Also note how we use the new HtmlHelper extension method, the selection of the

  • Source list (The IEnumerable<T>)
  • Option key value
  • Option text value

Is all done using Expression<Func<T,Object>> which is nice a type safe.

@model MvcApplication1.Models.PeopleViewModel
@using MvcApplication1.MyHelpers
@{
    ViewBag.Title = "PeopleView";
}


@using (Html.BeginForm("Create", "Home", FormMethod.Post))
{
    <h2>PeopleView</h2>

    <p>Select an item and click "Submit" button</p>
    
    @Html.ComboFor(
        x => x.SelectedPersonId, 
        x => x.Staff, 
        x => x.Id, 
        x => x.Name,
        new Dictionary<string, object> { { "class", "SomeSelectorClass" } })

    <br />
    <br />
    <br />
 
    if (ViewData["result"] != null)
    {
        <p>@ViewData["result"].ToString()</p>
    }
    
    
    <input id="peopleSubmit" type="submit" value="submit" />    
    
}

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

 

So when the HtmlHelper presented with this post does its job this is what the Razor view engine outputs

<select class="SomeSelectorClass" id="SelectedPersonId" name="SelectedPersonId">
<option value="1">Sam Brown</option>
<option selected="selected" value="2">Bob Right</option>
<option value="3">Henry Dune</option>
</select>

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

 

A Demo Controller

This is a small demo controller that goes with the model/controller supplied at the bottom of this post. Again you will need to change this depending on your own requirements

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using MvcApplication1.Models;

namespace MvcApplication1.Controllers
{
    public class HomeController : Controller
    {
      
        public ActionResult Create(PeopleViewModel vm)
        {
            List<Person> staff = new List<Person>();
            staff.Add(new Person(1, "Sam Brown"));
            staff.Add(new Person(2, "Bob Right"));
            staff.Add(new Person(3, "Henry Dune"));

            PeopleViewModel vmnew = 
                new PeopleViewModel(
                    vm.SelectedPersonId, staff);

            ViewData["result"] = 
                string.Format("The selected item was {0}",
                (from x in staff 
                 where x.Id == vm.SelectedPersonId 
                 select x).Single().ToString());
            return View("PeopleView", vmnew);
        }


        public ActionResult PeopleView()
        {

            List<Person> staff = new List<Person>();
            staff.Add(new Person(1, "Sam Brown"));
            staff.Add(new Person(2, "Bob Right"));
            staff.Add(new Person(3, "Henry Dune"));

            PeopleViewModel vm = new PeopleViewModel(2, staff);

            return View("PeopleView", vm);

        }
    }
}

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

 

ScreenShot

image

 

As always here is a small demo project. Enjoy

http://dl.dropbox.com/u/2600965/Blogposts/2011/11/SelectMVC.zip

Double Whammy

So I just got up this morning and turned on my PC and checked my emails, and low and behold I got some very good news. One of my recent Task Parallel Library articles http://www.codeproject.com/KB/cs/TPL1.aspx did very well in the monthly codeproject competitions, it won

  • Best overall article for the month
  • Best C# article for the month

Cool

JQuery Not Working With FireFox

For those of you that follow my blog, or know me you will know that I am mainly a WPF/WCF kind of guy, but I Do love ASP MVC, and thought of a tool that I wanted to use, and thought it would be best served as a web based app, so without further ado I set about getting stuck into some ASP MVC and JQuery.

All was going beautifully, my JQuery was coming along leaps and bounds, and was working in Internet Explorer/Firefox/Chrome, and then I changed something.

Suddenly JQuery stopped working entirely in Firefox, despite the fact that the Firebug FireFox addin reported no errors at all, and JQuery worked just fine in Internet Explorer and Chrome. This really hacked me off, and I annoyed my web developer colleague to death on this, and still nothing.

So I messed around for a while and worked out that to my surprise Firefox is far more finickity about how you declare you Javascript imports.

I was doing this

<script src="/Scripts/jquery-1.4.2.min.js" type="text/jscript"/>

Which as I say worked fine in IE/Chrome, but did not in Firefox, but alas no warnings either. After some Googling, I found a post on StackOverflow, that said for Firefox to work you must conform to the correct XHTML schema definition which means you must declare the script import with a correct end tag, like this:

<script src="/Scripts/jquery-1.4.2.min.js" type="text/jscript"></script>

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }But still no banana in Firefox…hot damn what is going on, still all was fine in IE and Chrome most peculiar.

Turns out the MIME time is all so very important for Firefox, you need to declare the import as follows, and all is then good:

<script src="/Scripts/jquery-1.4.2.min.js" type="text/javascript"></script>

I found this post to be pretty useful in determining what MIME types are supported by the various browsers:

http://krijnhoetmer.nl/stuff/javascript/mime-types/

Here is the relevant parts

text/javascript

Opera 7.54+
IE 5+
Firefox 1.0.7+
Safari 2.0.3+
iCab 3 Beta 394
Camino 2006021400

text/jscript

Opera 7.54+
IE 5+
Safari 2.0.3+

Ok its probably an old post, but put me on the right track.

Hope this post and the one above I linked to helps you not get stung like I did.
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

Just A Quick Note To Say What I am Up To

Its been a while since I did any serious blogging, I have not forgotten about my blog, far from it, I have just been quite tied up writing up articles of late, Cinch V2 kept me pretty occupied.

But anyway here is a list of things that I am up to, right now

Main Focus

Being a dad

Secondary Focus

So what else am I up to, well I am in the middle of creating a pretty large ASP .NET MVC project that is a tool that I think may help many developers. I don’t want to say too much about it, but I honestly think it will be a really really useful tool. What I can say is that you will be able to interact with the website right from inside VS2010 using a VS2010 addin, and that I will be releasing the code onto Codeplex, as another opensource project, and I will write it all up over at codeproject anyway, as the web site design uses some nice AJAX JQuery along with ASP .NET MVC, which I think might interest some folk by itself, and I shall also be talking about how to create a VS2010 add in, and of course I will explain what the tools job is, and hopefully you lot will see that it could be useful to you too.

And Finally

I have also been asked to be a technical reviewer for a friends book, which I will commence work on next week.

 

So as you can see I am still busy, its just that I tend to work on larger things these days, and that takes up more time, which leaves less time for blogging.

I do have a plan for a IPhone like control which I will write for WPF, when I find a spare minute.

 

Anyway just wanted to let you all know that, I am doing stuff, and that is what I am doing.

Cinch (Again)

As my last post on Cinch indicated I fixed a lot of stuff in the latest drop, there 1 or 2 areas where I forgot to fix things (though the code still works, but could have been improved, so I improved it).

I then had major headaches with SVN/Codeplex source code getting corrupted whilst I was trying to update codeplex, so I struggled with that for a long time on Saturday 08/05/2010.

So if you downloaded Cinch again, I would urge you to please download and use the latest drop where the codeplex realease tab states “All Fixed”.

As the comment indicates this has all fixes and is correct source control (SVN) wise.

I am now working on Cinch V2 which I think it going to be a much better API to work with.

Enjoy Cinch V1 for now, Ill keep you all post Re: Cinch V2.

There will also be a new demo app for Cinch V2 for both WPF and SL.

Cinch (My MVVM framework) Part 4 is out

I just published part III of my MVVM framework series over at http://www.codeproject.com .

Here is the link

http://www.codeproject.com/KB/WPF/CinchIV.aspx

 

This time I talk about

Developing Models Using Cinch
Developing ViewModels Using Cinch

    * Choosing a ViewModel Base Class
    * ViewModelBase Class
    * How To Use The Exposed Services
          o EventLogger service
          o MessageBox service
          o Open File service
          o Save File service
          o Popup window service
    * Background Tasks
    * Mode Support

 

Enjoy

Who Wants Me To Write A Book

Recently someone left me the following message on my new article (http://www.codeproject.com/KB/smart/GeoPlaces.aspx)

Hi Sacha,
I’m sure this has been said before but you really should write a book imho.
I’d buy it …
I’m not going to vote a 5 because I’d rather vote with my cash frankly!!
Oh, alright then … Wink
<stick>
Gold Star
</stick>
Seriously, write a book, but don’t do the predictable thing of picking a single technology. I like your whole approach and passion. This article would make a killer chapter in said book for instance …
Best Regards,

Jammer : 05/04/2009

Now this is not the 1st time someone has suggested that I write a book, I was just wondering how many people would actually like me to write a book. If you would could you leave a comment here, so that I can tell who would buy the book, and how many folk think it would be a good idea.

The sort of thing that I would try and cover is what I normally cover, which would be how to work with a mixture of technologies all used together, So this may include WCF/WPF/WF/LINQ/Custom controls/ASP .NET Silverlight all working together. Typically this would be to solve some problem that I make up, where the problem show cases how to use the technology really.

Let me know thanks

PS : I am running out of time to say thanks to all of you that have encouraged me to do this. I am going to look into it. I just wanted to say a big thanks to you all.

How To Create A WCF Client Proxy Without Having a Deployed WCF Service

At work we are currently using a very very Agile process, which involves 1/4 hourly builds, which was all going brilliantly with a WPF solution and some Mocks and some NUnit test projects. Then we got to the point where we had to start building our WCF service and have the WPF project obtain a new service reference client proxy based on the newly built WCF service project. This is easily achieved using NANT and wiring up dependencies in a NANT script, but we were not in a position where we could actual deploy the WCF Service with every build, due to the fact that we are hosting the WCF service inside a Windows service.

We could have also automated this using InstallUtil.exe to install the service, but this would have added more complexity to an already complex build arrangement within our CI build server AKA “Cruise Control”. We could have done it, but we simply wanted to be able to create a new service reference client proxy. Normally what one would do would be to add a service reference within Visual Studio, something like the figure shown below:

ServiceReference

When you add a service reference using Visual Studio, you typically have to have, the service both deployed and running, and you then point the wizard at the deployed and running service address, which exposes some metadata which allows the wizard to be able to see information about the service. This will then create a bunch of items in Visual Studio, such as the following :

ref

One of the these generated files is the service reference client proxy. In this case it is called “Reference.cs”, which if we examine a small section of it, contains all the DataContract / ServiceContract class definitions.

dc

Which is fine, but as I stated above, what was needed for a continuous build environment (Cruise Control) was the ability to create this service reference client proxy class “Reference.cs” without a deployed service. Mmmm, how could we do that.

Well luckily there is a command line tool which can be run as part of a NANT script. This utility is called “svcutil.exe”, and has many options, which you can find using the svcutil.exe /? switch.

But to help you out here is what we had to do in order to duplicate the functionality provided by the Visual Studio wizard using just svcutil.exe.

It was a 2 phase operation, the phases are as follows:

Create WSDL from Dlls

You can create a WSDL by using the Dlls themselves, and then you can use the WSDL to create a service reference client proxy class. Here is how we did this.

Switch Description
/d: /d:<directory> Directory to create files in (default: current directory)
/reference: /reference:<file path> : Add the specified assembly to the set of assemblies used for resolving type references.

svcutil /directory:c:SOMEDIRECTORY “<SERVICE CONTRACT DLL PATH>”
/reference:”<DATACONTRACT DLL PATH>”

NOTE : You may have all your ServiceContract and DataContract classes all in one Dll, so in this case you would not need the /reference: switch, this is only need to link in additional Dlls.

Use WSDL to create WPF client service reference proxy class

Once we had a WSDL we could the use this to create the create a service reference client proxy class. We did this as follows:

Switch Description
/d: /d:<directory> Directory to create files in (default: current directory)
/l: Language C# or VB
/out: Name of output file
/noconfig Do not generate a client layer App.Config file
/s /serializable : Generate classes marked with the Serializable Attribute
/ct /collectionType: <type> : A fully-qualified or assembly-qualified name of the type to use as a collection data type when code is generated from schemas.
/ser: /serializer: Auto – Automatically select the serializer. This tries to use the Data Contract serializer and uses the XmlSerializer if that fails.
/tcv: /targetClientVersion:Version35 : Generate code that references functionality in .NET Framework assemblies 3.5 and before.
/n: /namespace:<string,string> : A mapping from a WSDL or XML Schema targetNamespace to a CLR namespace.
/edb /enableDataBinding : Implement the System.ComponentModel.INotifyPropertyChanged interface on all Data Contract types to enable data binding.

svcutil
/d:c:SOMEDIRECTORY
c:SOMEDIRECTORY*.wsdl c:SOMEDIRECTORY*.xsd
/l:C#
/out:Reference.cs
/noconfig
/s
/ct:System.Collections.Generic.List`1
/ser:Auto
/tcv:Version35
/n:*,<THE NAMESPACE TO USE>
/edb

And that was enough for us to generate a new WPF client service reference proxy class in an automated manner, without the need to have the WCF service deployed and running.

Hope this helps someone out there

Visual Studio Templates “Out Of Date”

Today I started up my beloved Visual Studio 2005, and it said “No Visual Studio template information found”. Mmm. Bad news. Accepting this message, all my normal project types (templates) were not present. It turns out this is easiliy fixed with the following command line

C:Program FilesMicrosoft Visual Studio 8VC>devenv /installvstemplates

So if you get this message, simplu use that command line, and bingo your good to go again

NetPics : My MSc Project

NetPics Web Site : NetPics

I am currently doing my Msc at Sussex University, and as for my degree we have to do a final project. So I chose to do something like Flickr, where people could share media with friends. At the moment I only allow images to be shared, but this could be any media, such as video, music, documents etc etc.

The idea is that a web user may share with their friends, and the freind can log into the same portal and view the shared content. But I also wanted to write an app, that would allow the user to upload very quickly using standard desktop techniques such as drag and drop. In fact they should not even be aware that they actually creating web content. To this end the project will use a dektop application, and an ASP .NET web app, and the desktop app will upload content using a web service. Thats the basic idea anyway.

Although I am still doing my MSc, and this project is still under development. A few screen shots cant hurt now can it.

The Web Site

This uses ASP .NET, and will use custom ASP .NET controls, and Ajax to allow the user to drag around pictures to form new albums etc etc

np1.png

np2.png

np3.png

np4.png

The Desktop App

The desktop app is .NET 2.0 stuff all the way. C# of course. The user of the desktop app will be able to create albums, edit images, view a slide show of image etc

np5.png

np6.png

np7.png

The image editing is done, thanks to the use of the IPLab image processing library, by Andrew Kirillov. The IPLab is available here

I am hoping this will do even better than my BSc project. Ill let you know when ive done it, and its marked.