MVC.NET Html helper extension examples

Leave a comment

Here are some examples of HTML helper extensions and their respective HTML output.

mvc-helper-examples

Dropdown list

@Html.DropDownListFor(model => model.Package.State.Id, Model.PackageStates)            
<select data-val="true" data-val-number="The field Id must be a number." data-val-required="The Id field is required." id="Package_State_Id" name="Package.State.Id">
<option value="1">Received</option>
<option value="2">Processing</option>
<option selected="selected" value="3">Complete</option>
</select> 

I have a more indepth breakdown of dropdown list here.

https://agilewarrior.wordpress.com/2012/12/13/how-to-simple-html-dropdownlistfor-mvc-net/

Checkbox

@Html.CheckBoxFor(model => model.IsActive)            
<input checked="checked" data-val="true" data-val-required="The IsActive field is required." id="IsActive" name="IsActive" type="checkbox" value="true" /><input name="IsActive" type="hidden" value="false" />

Textbox

@Html.TextBoxFor(model => model.UserName)            
<input id="UserName" name="UserName" type="text" value="jrasmusson" />

Textarea

@Html.TextAreaFor(model => model.Poem, new {@rows = "6"})            
<textarea cols="20" id="Poem" name="Poem" rows="6">...</textarea>

Radiobutton

<span class="control-label">Do you agree to the Terms and Conditions?</span>
            <br />
            @Html.RadioButtonFor(model => model.TermsAndConditions, true, new {id = "TermsAndConditions_true", @class = "control-radio"})
            <label for="TermsAndConditions_true">Yes</label>
            <br />
            <span class="control-label">&nbsp;</span>
            @Html.RadioButtonFor(model => model.TermsAndConditions, false, new {id = "TermsAndConditions_false", @class = "control-radio"})
            <label for="TermsAndConditions_false">No</label>
            <br />
<input class="control-radio" data-val="true" data-val-required="The TermsAndConditions field is required." id="TermsAndConditions_true" name="TermsAndConditions" type="radio" value="True" />
            <label for="TermsAndConditions_true">Yes</label>
            <br />
            <span class="control-label">&nbsp;</span>
            <input checked="checked" class="control-radio" id="TermsAndConditions_false" name="TermsAndConditions" type="radio" value="False" />
            <label for="TermsAndConditions_false">No</label>

Radio button with Twitter Bootstrap

<span class="control-label">Do you agree to the Terms and Conditions?</span>
            <br />
            <div class="controls">
                <div class="btn-group" data-toggle="buttons-radio">
                    <button type="button" class="btn btn-primary" value="TermsAndConditions_true">Yes</button>
                    <button type="button" class="btn btn-primary" value="TermsAndConditions_false">No</button>
                </div>
            </div>

Here is the View in it’s entirety. Note this look and feel was done using Twitter Bootstrap.

Index.cshtml

@model Dashboard.Models.DashboardIndexModel

@{
    ViewBag.Title = "Index";
}

<h2>Index</h2>

<fieldset>
    <legend>Package</legend>
    
    <div class="form-horizontal">
        
        <div class="control-group">
            @Html.LabelFor(model => model.Package.State, new {@class = "control-label"})
            <div class="controls">
                @Html.DropDownListFor(model => model.Package.State.Id, Model.PackageStates)            
            </div>
        </div>
    
        <div class="control-group">
            @Html.LabelFor(model => model.IsActive, new {@class = "control-label"})
            <div class="controls">
                @Html.CheckBoxFor(model => model.IsActive)            
            </div>
        </div>
        
        <div class="control-group">
            @Html.LabelFor(model => model.UserName, new {@class = "control-label"})
            <div class="controls">
                @Html.TextBoxFor(model => model.UserName)            
            </div>
        </div>
        
        <div class="control-group">
            @Html.LabelFor(model => model.Poem, new {@class = "control-label"})
            <div class="controls">
                @Html.TextAreaFor(model => model.Poem, new {@rows = "6"})            
            </div>
        </div>
        
        <div class="control-group">
            <span class="control-label">Do you agree to the Terms and Conditions?</span>
            <br />
            @Html.RadioButtonFor(model => model.TermsAndConditions, true, new {id = "TermsAndConditions_true", @class = "control-radio"})
            <label for="TermsAndConditions_true">Yes</label>
            <br />
            <span class="control-label">&nbsp;</span>
            @Html.RadioButtonFor(model => model.TermsAndConditions, false, new {id = "TermsAndConditions_false", @class = "control-radio"})
            <label for="TermsAndConditions_false">No</label>
            <br />
        </div>
        
        <div class="control-group">
            <span class="control-label">Do you agree to the Terms and Conditions?</span>
            <br />
            <div class="controls">
                <div class="btn-group" data-toggle="buttons-radio">
                    <button type="button" class="btn btn-primary" value="TermsAndConditions_true">Yes</button>
                    <button type="button" class="btn btn-primary" value="TermsAndConditions_false">No</button>
                </div>
            </div>
        </div>


    </div>
    
</fieldset>

How to simple Html.DropDownListFor MVC.NET

19 Comments

dropdownlist-mvc

I find the Html helper APIs for ASP.NET MVC ackward and confusing. That’s why I like creating these little examples to figure out what is going on.

Here is a simple example of how to create a drop down list in ASP.NET MVC using Html.DropDownListFor.

You can do it like this all inlined in your *.cshtml file like so:

@Html.DropDownListFor(model => model.Package.State, new SelectList(
                  new List<Object>{ 
                       new { value = 0 , text = "Red"  },
                       new { value = 1 , text = "Blue" },
                       new { value = 2 , text = "Green"}
                    },
                  "value",
                  "text",
                   2))

With produces this:

<select id="Package_State" name="Package.State"><option value="0">Red</option>
<option value="1">Blue</option>
<option value="2">Green</option>
</select>

The model => model.Package.State expression is used to generate the id and name on the select.

The string value and text matter as they need to match the model attributes of the listItem in the list.

Or you can create your own List collection (with different fields for value and text) in your controller, set it on you model, and then use in your view like this:

    @Html.DropDownListFor(model => model.Package.State.Id, new SelectList(
                  Model.PackageStates,
                  "id",
                  "name",
                  Model.Package.State.Id))

Longer version

Here is a more indepth example with break down using modesl, view and controller.

Model

I basically have x3 models.

PackageState – contains the state of my package (fake domain object I made up).
Package – contains the PackageState and whatever else I want to throw in there.
DashboardIndexModel – this is how I bundle everything in the controller to send to the view.

PackageState.cs

    [Serializable]
    public class PackageState
    {
        private PackageState(int id, string name)
        {
            this.Id = id;
            this.Name = name;
        }

        public int Id { get; set; }
        public string Name { get; set; }

        public static PackageState Received = new PackageState(1, "Received");
        public static PackageState Processing = new PackageState(2, "Processing");
        public static PackageState Complete = new PackageState(3, "Complete");
    }

Package.cs

    public class Package
    {
        public PackageState State { get; set; }

        public Package(PackageState state)
        {
            State = state;
        }
    }

DashboardIndexModel.cs

    public class DashboardIndexModel
    {
        public Package Package { get; set; }
        public IEnumerable<SelectListItem> PackageStates { get; set; } // dropdown
    }

Controller

Here is where I prepare my dropdown list. I could do the work in the view (like the short example above). But here I have chosen to do it in the controller to keep the view clean and because I want to be able to set which element in my drop down should be selected.

    public class DashboardController : Controller
    {
        //
        // GET: /Dashboard/

        public ActionResult Index()
        {
            PackageRepository.Package = new Package(PackageState.Complete);
            IList<PackageState> states = new List<PackageState>
                                             {PackageState.Received, PackageState.Processing, PackageState.Complete};

            int selectedStateId = 2; // hard code for demo

            IEnumerable<SelectListItem> selectList =
                from s in states
                select new SelectListItem
                           {
                               Selected = (s.Id == selectedStateId),
                               Text = s.Name,
                               Value = s.Id.ToString()
                           };

            // Do this if you don't care about selection
//            List<SelectListItem> selectList = states.Select(state => new SelectListItem {Value = state.Id.ToString(), Text = state.Name}).ToList();

            var model = new DashboardIndexModel { Package = PackageRepository.Package, PackageStates = selectList };
            return View(model);
        }
    }

View

And here is the view showing x2 ways to create the dropdown list.

Index.cshtml

@model Dashboard.Models.DashboardIndexModel

@{
    ViewBag.Title = "Index";
}

<h2>Index</h2>

<fieldset>
    <legend>Package</legend>

    <div class="display-field">
        @Html.DisplayFor(model => model.Package.State.Name)
    </div>
    
    @Html.DropDownListFor(model => model.Package.State.Id, new SelectList(
                  new List<Object>{ 
                       new { value = 0 , text = "Red"  },
                       new { value = 1 , text = "Blue" },
                       new { value = 2 , text = "Green"}
                    },
                  "value",
                  "text",
                   2))
    
    
    
    @Html.DropDownListFor(model => model.Package.State.Id, Model.PackageStates)
    
</fieldset>

So that’s it. A simple of a dropdown. Don’t worry if you find these helpers confusing at first (I know I did at first too). But creating little experiments like this, and viewing the HTML output helps the understanding.

Links that help

http://stackoverflow.com/questions/5554421/dropdownlist-selectlist-selectedvalue-issue
http://stackoverflow.com/questions/3057873/how-to-write-a-simple-html-dropdownlistfor
http://stackoverflow.com/questions/781987/how-can-i-get-this-asp-net-mvc-selectlist-to-work

A minimalist HTTP WCF configuration

4 Comments

Wanting a simple example of how to spin up and host a WCF endpoint and proxy for integration testing, I came up with the following simple example.

IFooService.cs


using System.ServiceModel;
using System.ServiceModel.Web;

namespace Test.SomeDir
{
    [ServiceContract]
    public interface IFooService
    {
        [WebGet(UriTemplate = "/ping")]
        [OperationContract]
        string Ping();
    }
}

FooService.cs


namespace Test.SomeDir
{
    public class FooService : IFooService
    {
        public string Ping()
        {
            return "Ping";
        }
    }
}

FooServiceTest.cs


using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Description;
using System.ServiceModel.Web;
using System.Text;
using NUnit.Framework;
using Test.SomeDir;

namespace Test
{
    public class FooServiceTest
    {
        [TestFixture]
        public class When_spec
        {
            private ServiceHost host;
            private IFooService proxy;

            [SetUp]
            public void SetUp()
            {
                host = new WebServiceHost(typeof(FooService));
                host.Open();
                proxy = CreateProxy();
            }

            [TearDown]
            public void TearDown()
            {
                host.Close();
            }

            [Test]
            public void Should_observation()
            {
                proxy.Ping();
            }

            private IFooService CreateProxy()
            {
                EndpointAddress ep = new EndpointAddress("http://localhost:1980/abc");

                var binding = new CustomBinding(
                    new TextMessageEncodingBindingElement(MessageVersion.None, Encoding.UTF8),
                    new HttpTransportBindingElement { ManualAddressing = true });

                var factory = new ChannelFactory<IFooService>(binding, ep);
                factory.Endpoint.Behaviors.Add(new WebHttpBehavior());

                return factory.CreateChannel();
            }
        }
    }
}

The unit test above dynamically spins up a WCF WebServiceHost service which automatically sets some http bindings and behaviour configuration for us.

All we need to do now is add some information to our App.config file like this.

App.config

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

  <system.serviceModel>
    <services>
      <service name="Test.SomeDir.FooService"> <!-- this needs to be the fully qualified name of the service from your test -->
        <endpoint address="abc" binding="webHttpBinding" contract="Test.SomeDir.IFooService" /> <!-- address can be anything -->
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:1980" />
          </baseAddresses>
        </host>
      </service>
    </services>
  </system.serviceModel>
  
</configuration>

And voila! You are done.

Couple things to be aware of.

1. The name in the configuration has to exactly match fully qualified name used to spin up our host.

            [SetUp]
            public void SetUp()
            {
                host = new WebServiceHost(typeof(FooService));
                host.Open();
                proxy = CreateProxy();
            }

Needs to be expanded to the following in your config.

<service name="Test.SomeDir.FooService">

Get this wrong and you will get the following error:

System.InvalidOperationException : Service ‘Test.SomeDir.FooService’ has zero application (non-infrastructure) endpoints.

2. Note the end point address ‘abc’.

<endpoint address="abc"

This need to map to the path the immediately follows the base host address in your URL;

http://localhost:1980/abc

Hope this helps. I find writing a test like this useful for testing my end points and making sure I’ve got everything setup.

A good book for learning more WCF is Learning WCF: A Hands-on Guide

Silverlight Model-View-Presenter (MVP) example

2 Comments

The Model-View-Presenter is a great pattern for breaking apart separations of concerns in your applications.

The model holds your data and services.
The view holds your user interface controls and interactions.
The the presenter coordinates things behind the scenes.

It’s nice because it keep your business logic out the UI and it makes testing a lot easier as you can focus on just one layer of the application at a time.

Having used MVP a lot in ASP.NET applications, I wanted to see what it would look like in Silverlight and coded up this quick example for reference.

Let’s now see how MVP handles someone entering new user information on a page and hitting the save button.

The View

The view is our gateway into getting and controlling what the user sees on the screen.

UserAdminView.xaml

<UserControl x:Class="MVP1.View.UserAdminView" ...  d:DesignHeight="300" d:DesignWidth="400">
    
    <Grid x:Name="LayoutRoot" Background="White">

        <ListBox ScrollViewer.VerticalScrollBarVisibility="Disabled">

            <TextBlock Text="Username"/>
            <TextBox Name="userNameTextBox" Width="100" Height="25" />
            <TextBlock Text="Roles" />

            <StackPanel Orientation="Horizontal">
                <CheckBox Name="RequestorCheckBox"  />
                <TextBlock Text="Requestor"/>
            </StackPanel>

            <StackPanel Orientation="Horizontal">
                <CheckBox Name="ApproverCheckBox"  />
                <TextBlock Text="Approver"/>
            </StackPanel>

            <Button Name="SaveButton" Content="Save" Click="SaveButtonClicked"/>
            <TextBlock Name="Message" Foreground="Green" Text="Success" Visibility="Collapsed"/>

         </ListBox>
    </Grid>
</UserControl>

When the user hits the save button we need to know what the users name is and what roles they are going to be assigned. To do that we might define a view interface that looks like this:

IUserAdminView.cs

    public interface IUserAdminView
    {
        string ReadName();
        IList ReadRoles();
        void DisplayMessage(string userName);
    }

… and gets implemented like this:

UserAdminView.xaml.cs

    public partial class UserAdminView : IUserAdminView
    {
        private readonly UserAdminPresenter presenter;

        public UserAdminView()
        {
            InitializeComponent();
            presenter = new UserAdminPresenter(this, new UserRepository());
        }

        public string ReadName()
        {
            return userNameTextBox.Text;
        }

        public IList<string> ReadRoles()
        {
            IList<string> roles = new List<string>();
            if (RequestorCheckBox.IsChecked == true)
                roles.Add("Requestor");
            if (ApproverCheckBox.IsChecked == true)
                roles.Add("Approver");
            return roles;
        }

        public void DisplayMessage(string userName)
        {
            Message.Visibility = Visibility.Visible;
            Message.Text = string.Format("{0} was successfully added.", userName);
        }

        private void SaveButtonClicked(object sender, RoutedEventArgs e)
        {
            presenter.HandleAddUser();
        }
    }

ReadName(), ReadRoles() and DisplayMessage() interact directly with the view and do pretty much what you’d expect.

The SaveButtonClicked event hanlder however is a bit different.

       private void SaveButtonClicked(object sender, RoutedEventArgs e)
        {
            presenter.HandleAddUser();
        }

Because the view isn’t really in a position to handle saving the user, it passes this request off to the presenter who can (he’s got the view for reading data and the model for saving it).

But before we get into that guy let’s take a quick look at the model.

The Model

 public interface IUserRepository
    {
        void AddUser(string username);
        void UpdateUserRoles(string username, IList<string> roles);
    }

The Model often goes by more than one name. Some call it the Service layer. My friends like Task. Here I’ve called it IUserRepository because all we’re going to do is save the user to the database.

This example doesn’t actually talk to any databases, but if it did that code would go here (or a more likely some backend webservice):

public class UserRepository: IUserRepository
    {
        public void AddUser(string username)
        {
            // add user to the database
        }

        public void UpdateUserRoles(string username, IList roles)
        {
            // update the user roles
        }
    }

That’s it for the model. It just does the actual work of whatever we want to do and is usually called from the presenter.

The Presenter

 public class UserAdminPresenter
    {
        private IUserAdminView view;
        private IUserRepository repos;

        public UserAdminPresenter(IUserAdminView view, IUserRepository repos)
        {
            this.view = view;
            this.repos = repos;
        }

        public void HandleAddUser()
        {
            string userName = view.ReadName();
            IList<string> roles = view.ReadRoles();

            if (!string.IsNullOrEmpty(userName))
            {
                repos.AddUser(userName);
                repos.UpdateUserRoles(userName, roles);
                view.DisplayMessage(userName);
            }
        }
}

The presenter is where we bring it all together. We use our view to get the data and the model to save it. It coordinates whatever is going on in your view.

In this case there’s only one thing we’re doing. Adding a user. So when the Save button gets pressed our view passes control over to the presenter and it goes about using the view and model to do just that.

        public void HandleAddUser()
        {
            string userName = view.ReadName();
            IList<string> roles = view.ReadRoles();

            if (!string.IsNullOrEmpty(userName))
            {
                repos.AddUser(userName);
                repos.UpdateUserRoles(userName, roles);
                view.DisplayMessage(userName);
            }
        }

That’s it. That’s all there is to MVP.

How is this different from any other MVP implementation?

Not much.

Any differences will usually be in platform. The stateless (request/response) nature of the web means web events come at HTTP Posts. In Silverlight they come as .NET WPF events.

Other than that they are pretty much the same.

How is this different from MVC?

It’s not really that much different. Thick client MVC implementations, in my experience, use a lot of eventing for communication. I don’t like that.

I find heavy eventing hard to follow and difficult to debug. So much happens behind the scenes it can be hard to see where you are in the program. This isn’t an MVC problem. It’s more an implementation style (see last post for an example of heavy eventing).

What I like about MVP (and MVC implementations like Rails and MVC.NET) is the simple request response enforced by statelessness of HTTP. Fire event, something happens, update controls.

If I can maintain that simplicity my Silverlight applications (less rather than more events) I will usually go for that.

What about MVVM?

That’s on my todo list next. I want to try the data binding that comes with that and see how that compares to MVC and MVP.

Stay tuned.

In the meantime, here’s an article to get you started on MVVM.

You can download the source here for this example here SilverLight-MPV.doc (rename *.doc to *.zip – wordpress limitation).

Getting started with Watin, NUnit, and MVC.NET

2 Comments

Watin is a web application testing framework handy for writing high-level smoke screen tests against your .NET web application.

The website has a decent getting started section but I ran into one gotcha (really just a missing dll) and wanted to show you how to get it up and running quickly and easily using NUnit on a simple MVC.NET application.

Step 1: Download Watin

You can download Watin from the main website or just click here and download the lastest Watin 2.x release candidate.

Step 2: Create an empty web application.

For this example I created an empty ‘ASP.NET MVC2 Web Application’ and then added a ‘Class Library’ project to hold my Watin unit tests.

Step 3: Add references.

To run the Watin tests you need two dlls:

  • Watin.Core.dll
  • Interop.SHDocVw.dll

Add these (as well as nunit.framework.dll) to your unit test class library.

Step 4: Create config file to set thread state

Because Internet Explorer is not thread safe, we need to configure NUnit to run in single thread state mode (more details on why here).

Add a ‘Application Configuration File’ (i.e. App.config) to your unit test dll

and paste the following into your configuration file:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
   <sectionGroup name="NUnit">
    <section name="TestRunner" type="System.Configuration.NameValueSectionHandler"/>
   </sectionGroup>
  </configSections>
  <NUnit>
   <TestRunner>
    <!-- Valid values are STA,MTA. Others ignored. -->
    <add key="ApartmentState" value="STA" />
   </TestRunner>
  </NUnit>
</configuration>

Step 5: Write your test(s)

The Watin Getting Started section has a simple example to get you going.

using NUnit.Framework;
using WatiN.Core;

namespace tests
{
    [TestFixture]
    public class WatinTest
    {
        [Test]
        public void HelloGoogle()
        {
            // Open a new Internet Explorer window and
            // goto the google website.
            IE ie = new IE("http://www.google.com");

            // Find the search text field and type Watin in it.
            ie.TextField(Find.ByName("q")).TypeText("WatiN");

            // Click the Google search button.
            ie.Button(Find.ByValue("Google Search")).Click();

            // Uncomment the following line if you want to close
            // Internet Explorer and the console window immediately.
            //ie.Close();
        }
    }
}

When you run this test, your default browser should pop-up, enter ‘Watin’ in the search box, and then click the search button.

To run a test against your MVC.NET application, you need to start your webserver. Hit F5 to run your application, note the URL it starts up on (i.e. http://localhost:1110), and then edit the test below so it looks something like this:

        [Test]
        public void HelloMVC()
        {
            IE ie = new IE("http://localhost:1110");
            Assert.IsTrue(ie.Text.Contains("My MVC Application"));
        }

Congratulations! You’ve just written your first Watin test.

Next week we will dive deeper and look more closely at some specific Watin controls and how they work.

Simple msbuild file with nunit

Leave a comment

Quite often when starting a new project you need a build file. Here’s one I like to use to get things going.

 <Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <Import Project="$(MSBuildExtensionsPath)\MSBuildCommunityTasks\MSBuild.Community.Tasks.Targets"/>
  
  <!-- Application Configurations -->
  <PropertyGroup>
    <SolutionFileName>mvc2.sln</SolutionFileName>
    <NUnit-ToolPath>tools\nunit</NUnit-ToolPath>	
  </PropertyGroup>
  
  <ItemGroup>
    <AllProjects Include="**\*.csproj" />
  </ItemGroup>
  
  <Target Name="Clean">
    <MSBuild Projects="@(AllProjects)" Targets="Clean" />
  </Target>  

  <Target Name="Compile">
    <MSBuild Projects="@(AllProjects)" Targets="Build" Properties="WarningLevel=1" />
  </Target>
    
  <Target Name="Test" DependsOnTargets="Clean;Compile">
	    <NUnit ToolPath="$(NUnit-ToolPath)" DisableShadowCopy="true" Assemblies="test\bin\Debug\test.dll" OutputXmlFile="test-results.xml" />
  </Target>
       
  <Target Name="Build" DependsOnTargets="Clean;Compile;Test;" />

</Project>

Note: To run this build you will need to download and install msbuild community tasks.

This build works against a very basic directory structure:

  • src – basic dll for source code
  • test – basic dll for test code

And all it does is:

  • compile
  • clean, and
  • runs tests (via nunit)

Enjoy!

Part I – How to turn on the Microsoft Surface Table

3 Comments

This week I got the opportunity to play around with a Microsoft Surface Table (it’s kinda cool) but turning the bloody thing on was enough of a pain that I thought I would share the experience.

The first switch you need to turn on is the AC adapter located at the back of the table.

To get to the second switch you need to remove the kick plate panel at the end opposite of the AC adapter.

After you press and hold that one for a couple seconds the table should power up and you’ll be presented with the login screen. The manual is worth reading (it’s a bit tricky taking off the end plate as you need to unscrew a bolt). But once you get it off the switch is pretty visible.

%d bloggers like this: