I’m using ASP.NET MVC 3.
I was used to rely on filterContext.RouteData.Values to get parameters from the url
var idEdited = filterContext.RouteData.Values["id"];
This works fine as long as the url does not have specific parameters, like here:
http://www.mysite.com/myapplication/User/Edit/1234
However, when the parameter is not a routevalue anymore, like in the example below, then you would get a OfficeId= null when using the previous method :
http://www.mysite.com/myapplication/User/Edit/1234?OfficeId=567
When you are in that case, there is a way to get both the route value “id” and the parameter “OfficeId” using the ValueProvider :
var idEdited = filterContext.Controller.ValueProvider.GetValue("id").AttemptedValue;
var idEditedOffice = filterContext.Controller.ValueProvider.GetValue("OfficeId").AttemptedValue;
The ValueProvider will search into route values and url parameters (also in POST parameters, apparently).
thanks to http://stackoverflow.com/questions/6998809/question-about-routedata-and-valueprovider-on-asp-net-mvc3
I use MVC4 with razor.
I ran into the problem of formating correctly a DateTime property of my model that I render in the view using a TextBoxFor MVC helper. The default formatting displays the full date with hours, minutes and seconds :
@Html.TextBoxFor(m => m.BeginDate)
displays “27/04/2012 00:00:00” in the textbox. I only needed the first part so I wanted to use the ‘d’ format.
I then tried to use DataAnnotations to impose a format to the property to display:
[DisplayFormat(DataFormatString = "{0:d}")]
public DateTime BeginDate { get; set; }
Still, the generated textbox has the full date displayed : “27/04/2012 00:00:00”
There are actually 2 solutions to that :
1- Use DataAnnotations + EditorFor
The dataannotation DisplayFormat is actually NOT taken into account when the data is rendered with @Html.TextBoxFor helper. It applies only to the EditorFor helper.
So, keeping your dataannotation and replacing your helper by this shoud work :
@Html.EditorFor(m => m.BeginDate)
2 -Use TextBoxFor and alter the @Value parameter
If you really want your TextBoxFor, there is also a solution which I find less desirable since it tinkles with the default behavior of TextBoxFor.
You can remove the DisplayFormat data annotation and use this helper :
@Html.TextBoxFor(m => m.BeginDate, new { @Value = Model.BeginDate.ToString("d") })
I was looking for a kind of onselected trigger for the JQueryUI accordion (v 1.8.11). The proper way to do this is to use the “change” event of the accordion :
<script type="text/javascript">
$(document).ready(function () {
$("#accordion").accordion({
change: function (event, ui) {
alert("changed!");
}
});
});
Now, you might want to get the selected pane index. This is quite easy too :
<script type="text/javascript">
$(document).ready(function () {
$("#accordion").accordion({
active: 0,
change: function (event, ui) {
var activeIndex = $("#accordion").accordion("option", "active");
alert(activeIndex);
}
});
});
Lastly, you might have a hidden field of interest inside the selected pane that you want to access. Perhaps the accordion is constructed dynamically and each pane has an hidden field holding a value that you need.
We will use a jQuery selector to get it. I chose to rely on the class attribute to get all hidden ids and then to make use of the activeIndex to retrieve the right one.
<input class="HiddenId" type="hidden" value="1234"/>
Now, using a proper jQuery selector we are able to display that value when a new pane of the accordion is selected. The class HiddenId is what permits us to discriminate against different types of hidden fields, but you may chose to use a different attribute depending on the way the accordion contents are generated. Attributes Name or Id might work.
<script type="text/javascript">
$(document).ready(function () {
$("#accordion").accordion({
active: 0,
change: function (event, ui) {
var activeIndex = $("#accordion").accordion("option", "active");
var hidId = $("#accordion input[type=hidden][class=HiddenId]")[activeIndex];
alert($(hidId).val());
}
});
});
Testing for ModelState.IsValid when unit testing your controller is not straightforward, since the Model Binding is responsible for validating you model. But Model Binding happens in OnActionExecuted filter (and NOT when you call your controller Action method).
That means in your test context, Model Binding will not happen when you call your action method and ModelState.IsValid will always be true. But thanksfully, there is a solution below
If we have the following simplistic model :
public class UserModel
{
[Required]
[Display(Name = "First name")]
public string FirstName { get; set; }
[Required]
[Display(Name = "Last name")]
public string LastName { get; set; }
}
Along with the following simplistic Controller :
public class UserController : Controller
{
//
// GET: /User/
public ActionResult Index()
{
return View("Index");
}
//
// POST: /User/Create
[HttpPost]
public ActionResult Create(UserModel model)
{
if (!ModelState.IsValid)
return View("Error");
// perform creation (not implemented)
// and return Index view
return View("Index");
}
}
The following code will not work as expected :
[TestMethod]
public void TestErrorViewIsReturnedWhenInputIsNotValid()
{
// Arrange
var expectedViewName = "Error";
var controller = new UserController();
var badModel = new UserModel(){FirstName = "", LastName = ""};
// Act
var result = controller.Create(badModel) as ViewResult;
// Assert
Assert.IsNotNull(result);
Assert.AreEqual(expectedViewName, result.ViewName);
}
When we call controller.Create(badModel), no model binding occurs and ModelState.IsValid will be true.
If we want an effective Test, what we have to do is mimic the behaviour of the model binder which is responsible for Validating the Model. :
using System.ComponentModel.DataAnnotations;
[TestMethod]
public void TestErrorViewIsReturnedWhenInputIsNotValid()
{
// Arrange
var expectedViewName = "Error";
var controller = new UserController();
var badModel = new UserModel() { FirstName = "", LastName = "" };
// Act
// mimic the behaviour of the model binder which is responsible for Validating the Model
var validationContext = new ValidationContext(badModel, null, null);
var validationResults = new List<ValidationResult>();
Validator.TryValidateObject(badModel, validationContext, validationResults, true);
foreach (var validationResult in validationResults)
{
controller.ModelState.AddModelError(validationResult.MemberNames.First(), validationResult.ErrorMessage);
}
var result = controller.Create(badModel) as ViewResult;
// Assert
Assert.IsNotNull(result);
Assert.AreEqual(expectedViewName, result.ViewName);
}
What we do is validate the object and then feed the controller.ModelState with whatever errors we encountered.
And this is it, you can test the DataAnnotations of your model.
Many thanks to http://randomtype.ca/blog/how-to-test-modelstate-isvalid-in-asp-net-mvc/
If you're like me and are using MVVMLight to build Windows Phone apps, you probably want to unit test your ViewModels as well.
One of the benefits of the MVVM pattern is the separation of concerns between the View (page holding the xaml layout and bindings) and the ViewModel which holds the data to be bound.
This allows the ViewModel to be easily testable, or so they say. In the end, it is quite difficult to find some useable tutorial doing exactly that. To the point you might ask yourself : " do the people who use MVVMLight really do unit testing of their ViewModels ?"
After a great deal of research, I came up with a Tutorial of my own, thanks to
http://rabeb.wordpress.com/2011/08/14/mango-baby-steps-unit-testing-your-app/
and http://juarola.wordpress.com/2011/09/06/unit-testing-windows-phone-7-mvvmlight-viewmodels-with-7-1-sdk-rc-nunit-and-moq/
and http://www.jeff.wilcox.name/2011/06/updated-ut-mango-bits/
So let's do this.
We are going to build a testable WP7 MVVMLight project (named TestableWP7MVVMLight ), which is really a standard MVVMLight Project holding the ViewModels we want to test.
We are also going to build a unitTest project (named WP7MVVMLight.UnitTest) which will perform the unit testing of our first project.
Before starting, ensure having the following components installed on your system :
- Visual Studio 2010
- The Windows Phone 7.1 SDK (Mango)
- MVVM Light Toolkit installed on your Machine (use the MSi to install the project templates in VS2010 , the Nuget package does not do that, at least with the version I used). I used the v4 beta 1
Step 1: Creation of the MVVMLight application to be tested
Create a New MVVMLight (WP71) Project : TestableWP7MVVMLight 
Build the project and check that the application is functional. It should display "Welcome to MVVM Light" on the display.
Step 2 : Creation of the test project
Now, you might ask yourself : why not create a classic C# test project and reference our TestableWP7MVVMLight and then test it ?
Well, Silverlight and desktop applications use different CLR. It is not possible to reference a Silverlight (or WP7) assembly in a classic test project.
So what we do is create a New MVVMLight (WP71) Project: WP7MVVMLight.UnitTest

We will later rig up the test project with all the necessary testing assemblies
It should build flawlessly, as for the moment it is just another basic MVVMLight project.
Now we need to add the following Silverlight Unit Test Framework dlls to our project :
- Microsoft.Silverlight.Testing.dll
- Microsoft.VisualStudio.QualityTools.UnitTesting.Silverlight.dll
You will find those dlls here : http://www.jeff.wilcox.name/2011/06/updated-ut-mango-bits/
Check periodically Jeff Wilcox’s blog for up to date versions.
Now reference the two dlls in your WP7MVVMLight.UnitTest project
You will have VS2010 complain that "Adding reference to a Windows Phone XNA assembly is safe. However adding reference to a Silverlight assembly may lead to unexpected application behavior …" Ignore this and press Yes;
Your references should look like this :

Check that compilation goes well.
Step 3 : Run the empty test project
Now we need to edit the MainPage.xaml.cs file in order to have the WP7MVVMLight.UnitTest (which is still and will remain a windows phone app) actually running the tests and display results :
using Microsoft.Phone.Controls;
using Microsoft.Silverlight.Testing; // <--- Important
namespace WP7MVVMLight.UnitTest
{
public partial class MainPage : PhoneApplicationPage
{
// Constructor
public MainPage()
{
InitializeComponent();
const bool runUnitTests = true;
if (runUnitTests)
{
Content = UnitTestSystem.CreateTestPage();
IMobileTestPage imtp = Content as IMobileTestPage;
if (imtp != null)
{
BackKeyPress += (x, xe) => xe.Cancel = imtp.NavigateBack();
}
}
}
}
}
Note : editing the .xaml.cs file is not compliant with MVVM philosophy but in this instance, we have to do it .
Now if you run the WP7MVVMLight.UnitTest application, you'll get a dashboard of your test. Those tests will be automatically launched.
For the moment we have not tests, though
Step 4 : A first Test
We need first to reference our main phone app into the test project :

Then let’s create a test class inside a new folder named Tests

DemoTest.cs
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Ioc;
using Microsoft.Practices.ServiceLocation;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace WP7MVVMLight.UnitTest.Tests
{
[TestClass]
public class DemoTest
{
[TestMethod]
public void AlwaysWorkingUnitTest()
{
//Assert.Inconclusive("We need to write our first unit test");
Assert.AreEqual(1, 1);
}
}
}
And now, when you launch the WP7MVVMLight.UnitTest application, the test should execute and pass:

Now, let’s add this simple test method to our DemoTest.cs :
[TestMethod]
public void MainViewModel_ClassicInstanciation_UnitTest()
{
// Instantiate the viewModel we want to test
var mainViewModelToTest = new TestableWP7MVVMLight.ViewModel.MainViewModel(new TestableWP7MVVMLight.Design.DesignDataService());
// assert a property of the viewmodel
Assert.AreEqual(mainViewModelToTest.WelcomeTitle, "Welcome to MVVM Light [design]");
}
Here ! You are actually testing your viewmodel (the MainViewModel from the first TestableWP7MVVMLight project).
A little bit of explanation about what is going on here for people who are not familiar with the MVVMLight project template:
MainViewModel is instantiated with the design data service from DesignDataService.cs. It could really be any IDataService implementation , but I chose to use the DesignDataService from the original project. Of course, you could redefine another implementation of IDataService locally.
During instantiation of MainViewModel , the property WelcomeTitle is set based on the dataservice passed to the constructor; (this is really the pre-existing logic inside our TestableWP7MVVMLight MainViewModel.cs file )
So we explicitely instanciated a ViewModel and checked some property. But instead doing that, couldn’t we just use the IOC
Step 5 : Same but different : using the IOC
Here is the exact same test, but the instantiation of the ViewModel is made through a call to GetInstance.
The ViewModel is previously registered, as well as the implementation of IDataService which is to be used throughout the test
[TestMethod]
public void MainViewModel_IOCInstanciation_UnitTest()
{
// Set up the IOC
SimpleIoc.Default.Register<TestableWP7MVVMLight.Model.IDataService, TestableWP7MVVMLight.Design.DesignDataService>();
SimpleIoc.Default.Register<TestableWP7MVVMLight.ViewModel.MainViewModel>();
// Instantiate the MainViewModel - MVVM Style
var vm = ServiceLocator.Current.GetInstance<TestableWP7MVVMLight.ViewModel.MainViewModel>();
// assert a property of the viewmodel
Assert.AreEqual(vm.WelcomeTitle, "Welcome to MVVM Light [design]");
}
Great. You can now be happy and unitTest your ViewModels in true MVVM style.
Discussion
At that point, I am not aware of a way to leverage this inside an Industrialization process.
Since the actual testing and test results are done from the Windows Phone GUI, it does not seem possible to have automated tests being performed as a Build task for example.
If you have any suggestion on the subject, please leave me some comments.