As I’m sure you noticed, MVC RC1 is out now. In reading through the release notes I found this:
“The overloads for DropDownList and ListBox helper methods were reworked to fix various usability problems that were reported by customers.”
As I’m sure you noticed, MVC RC1 is out now. In reading through the release notes I found this:
“The overloads for DropDownList and ListBox helper methods were reworked to fix various usability problems that were reported by customers.”
By some strange combination of beta and pre-release candidate installs I managed to create some serious conflicts with ASP.NET MVC. Thereby producing this wonderful little error:
Compiler Error Message: CS0433: The type 'System.Web.Mvc.FormMethod' exists in both 'c:\WINDOWS\assembly\GAC_MSIL\System.Web.Mvc\1.0.0.0__31bf3856ad364e35\System.Web.Mvc.dll' and 'c:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files\root\06c0b3cf\32bec25d\assembly\dl3\71bfb65b\e11bf5c5_9e55c901\System.Web.Mvc.DLL'
I am using my own build of the source from codeplex so that I can debug through it to improve my knowledge of the codebase. From research online it looks like the assembly version between the latest pre-release and the beta weren’t incremented, or the web-runner tries to look in the GAC before the /bin, or the evil garden gnomes are at it again, or Microsoft wants to punish me for building THEIR dll files.
To solve this problem, i opened up the AssemblyInfo.cs files of the Mvc project and upped the AssemblyVersion to 1.0.0.9. Then hacked my web config to use that version. As I’m running in debug mode, and can’t sign the assembly I also had to remove the PublicKeyToken from the reference.
<add assembly="System.Web.Mvc, Version=1.0.0.9, Culture=neutral"/>
And suddenly we’re back in business.
I laid this out in more detail on the forums here:
http://forums.asp.net/p/1317154/2610342.aspx#2610342
I thought I’d mention it to this group so that people were aware of this difference between the interaction the old ParameterBinders and Rescues in version 4 and the new ModelBinders and HandleErrorAttributes of version 5.
The new way of doing parameter binding expects all errors to be placed into the ModelStateDictionary specified in the GetValue method.
public override object GetValue(ControllerContext controllerContext, string modelName, Type modelType, ModelStateDictionary modelState) {
The ModelStateDictionary can then be checked in the controller for errors via ViewData.ModelState.IsValid
I think the idea is that multiple binding errors can then be reported to the user at one time:
foreach (var value in ViewData.ModelState.Values)
{
value.Errors…..
}
Unfortunatly our current NameValueDeserializer that is used by the DeserializeAttribute throws exceptions when it encounters errors. These exceptions are NOT caught by Rescues / HandleErrorAttributes. The ControllerActionInvoker (in preview 5) calls
IDictionary
before the try/catch block that passes off errors to the HandleErrorAttributes. So if you’re using any kind of attribute deserialization and expecting your exceptions to be displayed all pretty like in your rescues… then move line #177 to line #180 of your ControllerActionInvoker.cs :)
-Will
Files: MvcTestingFramework.rar – or – MvcTestingFramework.zip
Back in November, ScottGu gave us some great examples on how to use the (then unreleased) MVC Framework. A major advantage of this framework is to be in the ease of testing. One of the classes used in that demo was a TestViewEngine that was implemented to determine what variables were passed to RenderView and RedirectToAction.
Since then we’ve learned that it was some private class that wasn’t in the framework. In December, Phil Hack recommended subclassing as a means to get at the RenderView which he admits leaves a certain bad taste in some people’s mouths.
I’m one of those people.
He also went on to explain that it can be done through mocking with RhinoMocks but then changed his mind saying that it wouldn’t build against the actual CTP version of the framework. (Thanks, you tease.) Then there was the concept of putting it in an extension method, but that prevents us from properly setting the stage for our tests.
There is also an issue with testing TempData in controllers even if you manage to get around the RenderView problems via subclassing. Ben Scheirman recommended doing this through mocking using SetupResult. Justice Gray then chimes in that something similar can be done for mocking Request.Form.
Seeing all this chaos, and knowing that there had to be a better way, I’ve combined a number of these recommendations into a framework that allows for easy and effective testing of ControllerActions.
It uses a bunch of Mocking, Reflection, and Dynamic Proxies to get the job done.
If you’re like me you’ve already downloaded the rar file at the top of the page. Please direct your attention to the MvcTestingFramework.Sample.Test project in the StarsControllerTest.cs file. Here’s you’ll find some simple uses of the framework.
[Test]
public void ListControllerSelectsListView()
{
MvcTestHandler handler = new MvcTestHandler();
StarsController controller = handler.CreateController<StarsController>();
controller.List();
Assert.AreEqual("List", handler.RenderViewData.ViewName);
}
Note that we’re creating an instance of MvcTestHandler in this and every other test case in this class. This handler performs several functions, namely creating our Controllers and populating them correctly. We’re also able to get at the parameters used in the RenderView method call by our ControllerAction via the RenderViewData class.
[Test]
public void AddFormStarShouldRedirectToList()
{
MvcTestHandler handler = new MvcTestHandler();
StarsController controller = handler.CreateController<StarsController>();
controller.AddFormStar();
Assert.AreEqual("List", handler.RedirectToActionData.ActionName);
}
Again, we’re able to access the ActionName from the handler’s RedirectToActionData class.
[Test]
public void AddFormStarShouldSaveFormToTempData()
{
MvcTestHandler handler = new MvcTestHandler();
StarsController controller = handler.CreateController<StarsController>();
handler.Form["NewStarName"] = "alpha c";
controller.AddFormStar();
Assert.AreEqual("alpha c", controller.TempData["NewStarName"]);
}
We simulate a form request, then read it back in from the controller’s TempData member. Do that with a controller that you make via a standard constructor and you won’t have such good results.
The MvcTestingFramework relies on two great frameworks, the Castle DynamicProxy framework and the aforementioned RhinoMocks framework.
After establishing a proxy of the given controller, the existing RedirectToAction and RenderView methods are changed so that they save the parameters and don’t actually redirect or render a view.
One particular annoying part (and there were several, saved only by The Reflector) was that a couple of objects types used by RedirectToAction are marked as internal, so I was forced to iterate over the properties looking for the Action and Controller properties. MS… Please, no more hoops and lions.
The one area that I don’t have working is Session variables. (You’ll note those unit tests fail.) Hopefully someone more familiar with Rhino Mocks will be able to get this working.
From the bottom of the Entity Framework Beta 3 docs on Query Execution, “The EndsWith method can also return different results because SQL Server considers two strings to be equal if they only differ in trailing white space, whereas the CLR considers them to be not equal.” That’s not exactly clear, so I spent some time trying out different scenarios.
Database Field ColorName : ‘Blue ’ // 3 spaces
SQL Query: … WHERE ColorName LIKE ‘%e ’
Returns 1
SQL Query: … WHERE ColorName LIKE ‘%e’
Returns 0
SQL Query: … WHERE ColorName = ‘blue’
Returns 1
SQL Query: … WHERE ColorName = ‘blue ’
Returns 1
LINQ Query … where c.ColorName.EndsWith(‘e’) select c;
Returns 0
LINQ Query … where c.ColorName.EndsWith(‘e ’) select c;
Returns 0
LINQ Query … where c.ColorName.EndsWith(‘ ’) select c;
Returns 1
LINQ Query … where c.ColorName.Trim().EndsWith(‘e’) select c;
Returns 1
LINQ Query … where c.ColorName.Trim().EndsWith(‘e ’) select c;
Returns 1
Database Field ColorName : ‘Blue’
SQL Query: … WHERE ColorName LIKE ‘%e ’
Returns 0
SQL Query: … WHERE ColorName LIKE ‘%e’
Returns 1
SQL Query: … WHERE ColorName = ‘blue’
Returns 1
SQL Query: … WHERE ColorName = ‘blue ’
Returns 1
LINQ Query … where c.ColorName.EndsWith(‘e’) select c;
Returns 1
LINQ Query … where c.ColorName.EndsWith(‘e ’) select c;
Returns 1
LINQ Query … where c.ColorName.EndsWith(‘ ‘) select c;
Returns 1
LINQ Query … where c.ColorName.Trim().EndsWith(‘e’) select c;
Returns 1
LINQ Query … where c.ColorName.Trim().EndsWith(‘e ’) select c;
Returns 1
So basically if you want to find a string that actually ends with a ‘ ’ using LINQ to Entities, best to use something other than EndsWith. This is certain to cause some major headaches for someone, so hopefully it gets fixed before the EF is out of beta.
I’ve spent some time yesterday and today playing around with the new Entity Designer GUI and Framework. So far I’m impressed with the possibilities and bothered by simple things that could cause repetitive headaches. Here are a few suggestions that I’d offer to the Entity Designer team:
To illustrate points three and four above, I’ve made myself a very simple database which might represent maternal genealogies, perhaps for someone studying Mitochondrial DNA.

As you can see, each person has a foreign key to another person who happens to be that person’s mother. Importing this into the Entity Designer via the wizard gives us two very cryptic columns called Person1 and Person2. Conceptually we might understand that each person has both a reference to her mother as well as a reference to all of her daughters. So one of these keys is a singular reference that we’d like to rename to “Mother” and another that we’d like to rename to “Children”. Examining these Navigation Properties in the designer shows:

Person 1

Person 2
Both of them have public getters and setters, both use the same Association, and neither of them list what type they return. To figure how to rename these, we must go to the generated c# code. (We can’t get to the xml code easily after all.)

So we can see from here that Person1 should be our Children/Daughters and Person2 should be Mother. Now we can rename these links appropriately.
Taking a look at a different example will illustrate my comment about ignoring foreign key names. This database is very simple with two tables as follows.

Importing this into the Entity Designer shows:

Now this is a bit easier than the previous problem to fix as the designer shows that the Association is liked to either “LastBrokenBy” or “LastFixedBy”. Is fixing all of these names part of the expected standard process of setting up the Entity Design?
Powered by WordPress