Wednesday, August 31, 2011

HP's QuickTest Professional (QTP)

...is being set up for our full system tests this sprint.

we are using the LINQSPECS open source library and not just LINQ

http://linqspecs.codeplex.com

a test I broke

We have a test that starts out like so:

[TestMethod]

public void FooControllerViewAllActionSecurityTest()

{

   var actionName = "Index";

   var controller = new FooController();

   var type = controller.GetType();

   var authAttribute = GetAuthorizedRolesAttribute(type, actionName, new Type[] {

         typeof(FooModel), typeof(BarModel), typeof(int))

      });

 
 

...which does a few other complicated things to test security. Some of it is done by GetAuthorizedRolesAttribute which expects the appropriate parameters for an action method's definition to be handed into it. The test fails if the wrong parameters are handed in. I broke this test yesterday, but fixed it today.

one may bind to two models at once upon POST

[HttpPost]

public ActionResult Index(ModelOne modelOne, ModelTwo modelTwo)

{

   
Whatever...

}

Tuesday, August 30, 2011

What I did today!

Today:
  1. Today Kar-Khan pointed out to me the my get/setter-based approach to jumping through a bunch of hoops immediately upon model binding which I crafted here, refined here, and then had Joel refine here, is just goofy. It is better to just have plain Jane get/setters and then call a method to do more complicated things with them beyond get and set. It didn’t want to do this because it entails putting an extra line of code in the Controller, but boy is that ever the lesser of the two evils compared to the mess I've been making.
  2. I added the following to our Base Class for Repositories:

    public virtual IQueryable<T> FindFilteredSet(List<Specification<T>> specifications)

    {

       Specification<T> currentSpecification =

             new AdHocSpecification<T>(t => t != null);

       IQueryable<T> results =

             Session.Query<T>().Where(currentSpecification.IsSatisfiedBy());

       foreach(Specification<T> specification in specifications)

       {

          IQueryable<T> concatenatedResults =

                Session.Query<T>().FindAll(specification).FindAll(currentSpecification);

          currentSpecification = specification;

          results = concatenatedResults;

       }

       return results;

    }

     
     

    Joel refactored my work like so:

    public virtual IQueryable<T> FindFilteredSet(List<Specification<T>> specifications)

    {

       var query = Session.Query<T>();

       specifications.ForEach(spec => query.Where(spec.IsSatisfiedBy()));

       return query;

    }

     
     

    Joel told me that foreach is old school and that I should try to use Select instead where applicable although it is not applicable in this case.
  3. We are taking the approach above in lieu of chaining specs in the name of a cleaner process outside of logic nested in Controllers which may also be encapsulated to play nicely with a comparable means devised for filtering based upon custom attributes. (I am building specifications for filtering on the static parameters of objects and the static parameters of their children in this example.)

Ctrl-Period renames a variable

If you rename a variable where it is first instantiated and you wish to make the change cascade to everywhere the variable's name is used, press Ctrl-Period. I believe this is a shortcut of Visual Studio itself and not a shortcut of Resharper.

What do you want from me? It's so hard to tell!

How does one interact with a method with a complicated interface like so:

TryParseValue(this object value, Type propType, out object result, out string errorMsg)

 
 

  1. There are three values you must hand in and not four. The first value, this, is handed over by way of chaining on .TryParseValue(a,b,c) to the end of it.
  2. The first alert as to the desired shape that I saw when moving my mouse pointer over empty parenthesis was:
    (this object value, Type propType, out object result, out string errorMsg):bool
  3. .TryParseValue(typeof (Boolean), out myObject, out emptyString); is the ultimate shape of things. If one leaves off one of the outs in this call one will be flagged with: Argument is 'value' while parameter is declared as 'out' ...when one mouses over the stuff in parenthesis.

Monday, August 29, 2011

log a bug in Team Foundation Server

  1. Open the appropriate list of tasks in the TFS Team Explorer.
  2. Right-click somewhere in the list and then select "New Linked Work Item..."
  3. Set the "Work Item Type" dropdown to "Bug"
  4. Complete the rest of the form and save.

add debug flags to a console app project

...by right-clicking on the project in the Solution Explorer and selecting "Properties." At the pane that appears there will be a tab for "Debug" which will have a fill-in-the-blank box for "Command line arguments" wherein one may add things like this:

-interactive:true -debug:true

BETWEEN

There is a BETWEEN Operator in SQL which allows for use like so:

SELECT * FROM employee WHERE Start_Date BETWEEN '1-1-82' AND '12-31-06'

strange to have setters without getters

I have refactored my doings from yesterday and the day before as is shown here. Joel thought it was too strange to have setters without getters. He felt the code would be difficult for others to follow.

using System;

namespace MyApp.Helpers

{

   public class SearchParametersForFoo : AttributeNormalizationLayer

   {

      public string Name

      {

         get

         {

            if (Get("Name") == null) return null;

            return Get("Name").ToString();

         }

         set

         {

            Set("Name", value);

         }

      }

      

      public Int32? Number

      {

         get

         {

            if (Get("Number") == null) return null;

            return Convert.ToInt32(Get("Number"));

         }

         set

         {

            Set("Number", value);

         }

      }

   }

}

 
 

The base class:

using System.Collections;

namespace MyApp.Helpers

{

   public class AttributeNormalizationLayer

   {

      public Hashtable Collection = new Hashtable();

      

      public void Set(string name, object value)

      {

         if (value != null)

         {

            Collection.Add(name, value.ToString());

         }

      }

      

      public object Get(string name)

      {

         var returnValue = (object)Collection[name];

         return returnValue;

      }

   }

}

Sunday, August 28, 2011

refactoring yesterday's mess

I have refactored the mess I made yesterday like so:

using System;

namespace MyApp.Helpers

{

   public class SearchParametersForFoo : AttributeNormalizationLayer

   {

      public string Name

      {

         get { return null; }

         set

         {

            Append("Name", value);

         }

      }

      

      public Int32? Number

      {

         get { return null; }

         set

         {

            Append("Number", value);

         }

      }

   }

}

 
 

The action:

[HttpPost]

public ActionResult Index(SearchParametersForFoo searchParametersForFoo)

{

   Hashtable hashTable = searchParametersForFoo.Collection;

   
more code follows...

 
 

The base class:

using System.Collections;

namespace MyApp.Helpers

{

   public class AttributeNormalizationLayer

   {

      public Hashtable Collection = new Hashtable();

      

      public void Append(string name, object value)

      {

         if (value != null)

         {

            Collection.Add(name, value.ToString());

         }

      }

   }

}

Saturday, August 27, 2011

must have the get with the set when binding to a model on [HttpPost]

It turns out that a get/setter must have the get half of the equation (the get) for the settings to work upon model binding by post-to-action means. The get has to return something or else the set fails to set. Note the extraneous getters in this class:

using System;

namespace MyApp.Helpers

{

   public class SearchParametersForFoo

   {

      public AttributeNormalizationLayer Parameters = new AttributeNormalizationLayer();

      

      public string Name

      {

         
get { return ""; }

         set {

            Parameters.Append("Name", value);

         }

      }

      

      public Int32 Number

      {

         
get { return 0; }

         set {

            Parameters.Append("Number", value);

         }

      }

   }

}

 
 

It would be nice if I could just leave out the lines in black above, but if I do this binding won't work.

[HttpPost]

public ActionResult Index(SearchParametersForFoo searchParametersForFoo)

{

   Hashtable hashTable = searchParametersForFoo.Parameters.Collection;

   
more code follows...

 
 

As it is, what I’m attempting is really kludgy. I'm trying to spool up a bunch of parameters related to filtering down a list of Foo into a Hashtable for handing to another class that will run a query based upon what is in the Hashtable which serves as a universal container for search parameters. Maybe this class should be a base class instead of a parameter on my Foo-specific object. I'm still working that out.

using System.Collections;

namespace MyApp.Helpers

{

   public class AttributeNormalizationLayer

   {

      public Hashtable Collection = new Hashtable();

      

      public void Append(string name, object value)

      {

         Collection.Add(name,value.ToString());

      }

   }

}

 
 

Or, well, honestly. I don't think there is any ambiguity. It should be a base class.

What am I trying to do? We need to be able to filter/search against a number of domain objects. (Many of these objects will have custom attributes in addition to static attributes.) We need one way of doing it and I am going to need to be able to hand to an API, that Kar-Khan will expose, a Hashtable of items to include in a query. The Hashtable will have an <A,B> format for WHERE A like 'B' flavored searching. Joel's whiteboarding from yesterday gives a high-level view here:

Addendum 8/22/2015: I am commenting out http://a.yfrog.com/img615/1945/t494.jpg which yfrog has seen fit to replace with some sort of iTunes advertisement. I wish I had not started up my blog hosting images with these clowns.

Friday, August 26, 2011

Ctrl-U in Firefox

...will allow you to view the source code for the web page you are at.

Hashtable

A Hashtable is a CLR type that is basically a Dictionary of <object,object> shape.

COMB

There is something for NHibernate called COMB which makes Guids sequential. The current date/time is embedded as part of the algorithm and as a result the Guids may be been in a sequential order. In simpler database scenarios in which one uses an autoincrementing integer for a table's key column, one may easily look at the rows in the table and tell which one was made first, which one was made second, etc. COMB allows for as much in the Guid world.

I guess the whole situation begs for a refactoring.

Which lines below seem not to belong in a controller action?

[HttpPost]

public ActionResult Edit(FooModel fooModel, Guid id)

{

   Foo foo = ProgramRepository.GetById(id);

   foo.Name = fooModel.Foo.Name;

   foo.Description = fooModel.Foo.Description;

   fooModel.Foo = foo;

   fooModel.Save();

   return RedirectToAction("Index");

}

 
 

The lines in white here are the lines that should be kept.

[HttpPost]

public ActionResult Edit(FooModel fooModel, Guid id)

{

   Foo foo = ProgramRepository.GetById(id);

   foo.Name = fooModel.Foo.Name;

   foo.Description = fooModel.Foo.Description;


   fooModel.Foo = foo;

   fooModel.Save();

   return RedirectToAction("Index");

}

 
 

So why the extra lines. In this case FooModel has numerous get-setters including a wrapper for the domain object itself like so:

public string Name { get; set; }

public string Description { get; set; }

public bool IsActive { get; set; }

public bool IsOfBar { get; set; }

public Foo Foo { get; set; }

 
 

Foo itself has these get-setters:

public string Name { get; set; }

public string Description { get; set; }

public bool IsActive { get; set; }

public bool IsOfBar { get; set; }

 
 

When editing Foo, the View contains two checkboxes for IsActive and IsOfBar and these get mapped to the wrapper upon model binding. Then the .Save() method will assign the values for the checkboxes to the IsActive and IsOfBar on the Foo inside FooModel and ultimately "Save" the Foo as the method name suggests. This is not my code. It is Mike's. But, I had to get saving working for Name and Description. In keeping with the checkboxes, I wrote Razor form fields like so:

@Html.EditorFor(model => model.Name)

 
 

Instead of like so:

@Html.EditorFor(model => model.Foo.Name)

 
 

Instead of like so:

Unfortunately, this sabotaged our jQuery sanity checking that is made to work with the fields on domain objects, so I ultimately had to use the later means above. Komali and I looked into this yesterday. It was her last day. I guess the whole situation begs for a refactoring.

Thursday, August 25, 2011

Wednesday, August 24, 2011

Debug Configuration Manager

Under the Debug dropdown in Visual Studio there is a Configuration Manager wherein one may make a project specific version of "Debug" that does not compile certain projects.

more IQueryable magic

A line of code starting with var foo = and ending with...

 
 

.Where(p => p.Id == id).OrderBy(p => p.Name); shows off the power of IQueryable. In this case the second half is bound to GetAll() which is explained here.

a much better way to make links in Razor

@Html.ActionLink("Don't touch me", "Details", "Object", new { foo = "bar", baz = "qux" }, new { style = "text-decoration: line-through !important;" })

 
 

This is a much better way to do Razor links than this way. Jitendra Patil pointed it out to me today. The five parameters are:

  1. the name that will appear to a user for the link
  2. the Action
  3. the Controller
  4. URL line variables
  5. HTML in-line parameters for the link

Tuesday, August 23, 2011

Automagically new up an object upon model binding!

public class FooModel

{

   public Foo Foo { get; set; }

   public string SomethingElse { get; set; }

   public string SomethingMore { get; set; }

   
more code follows...

 
 

What if you have a view model that wraps a domain object such as in the case above wherein a Foo is one of many get-setters on FooModel? And, what if you bind to the model after posting a form as given here?

[HttpPost]

public ActionResult Create(FooModel fooModel)

{

   
more code follows...

 
 

Let's say you have a form field named SomethingElse, but not one named SomethingMore. Well, then it stands to reason that (when you submit the form) the controller action shown above will bind a value to SomethingElse and that fooModel will end up with that value for SomethingElse while having a null value for SomethingMore. As SomethingMore has a null value, it is pretty safe to bet that Foo has a null value too as certainly a form is not going to have a field to correspond to a complex, custom type. There is no reason to believe that an instance of an object will be instantiated for Foo. However, what if we took this line in our view...

@Html.EditorFor(model => model.SomethingElse)

 
 

...and made it this line...

@Html.EditorFor(model => model.Foo.SomePropertyOnFoo)

 
 

Now when the form posts it maps user-driven content to a get-setter on Foo which is in turn a get-setter on FooModel. A Foo will be "newed up" in this process. Why does this matter? It has bearing as to whether you need to new up Foo before casting properties to it from other parts of FooModel in advance of saving Foo. I ran into a pain point today wherein I replaced something like the line above with something like the line just above it. In this scenario, where Foo had always been instantiated in my Action (and I could assign stuff to its get-setters), it ceased to be (and code blew up at the point of first assignment). It was a little tricky to understand what was lacking since I had no memory of newing up a Foo to begin with given that it was happening for me behind the scenes.


Ta-Da! It's magic!

Compare in TFS

Right-click in a file in Visual Studo and pick: Source Control > Compare... to bring up the a comparison between the current file and what was last tucked away to Team Foundation Server.

Source Control > View History ...will bring up a history tab for the file. Herein, one may right-click on any one line item in the history and pick Compare...

get an object's name with reflection

Get the name of an object including the strongly-typed dot dot dot path with reflection:

string whatever = typeof(Foo).ToString();

more NHibernate and Entity Framework wackiness

In our data project there is a "Mapping" folder with a .tt inside of it that contains all of our .hbm.xml files. This is a VERY interesting project.

One may right-click on this .tt model and pick "Run Custom Tool" to... update the mappings on the other side of a database update??? I'm a little hazy on "Run Custom Tool" :P

Update the database by right-clicking in the .edmx in the Core project and picking "Generate Database from Model..." which will in turn allow for saving an .sql file adjacent to the .edmx file in the same folder. (Right-click in a SQL file in Visual Studio and pick "Execute SQL" to run the script.)

TempData

I used TempData to solve this problem.

public static string tempVariableName = "Whatever";

   

public ActionResult Edit(Guid id)

{

   var fooModel = GetTheModelSomehow(id);

   return View("Create", fooModel);

}

   

[HttpPost]

public ActionResult Edit(FooModel fooModel, Guid id)

{

   SaveTheModelSomehow(fooModel);

   TempData[tempVariableName] = id.ToString();

   return RedirectToAction("Details");

}

   

public ActionResult Details(string id)

{

   if (TempData[tempVariableName] != null && id.IsNullOrEmpty())

   {

      id = TempData[tempVariableName] as string;

   }

   Guid guidKeyForMatching = new Guid(id);

   var fooModel = GetTheModelSomehow(guidKeyForMatching);

   return View(fooModel);

}

 
 

Imagine, if you will, that the above code is a piece of a controller that governs Foo. One may enter screens for just viewing non-editable details on an existing Foo or for actually editing an existing Foo by way of passing a Guid in the URL line. When one submits a form at the Create view the form reposts to the same URL taking one to the middle action above which in turn, after updating the Foo in question, takes one back to non-editable details.

time to get off of Cassini?

Our app is using "{controller}/{action}" as a default route instead of "{controller}/{action}/{id}" as there is some other home-rolled service that wraps the routing that throws a fit when UrlParameter.Optional is injected into Global.asax.cs like so:

new { controller = "Home", action = "Index", id = UrlParameter.Optional }

 
 

So what are my options for passing an id? I could so this...

return RedirectToAction("Details", new { id = id } );

 
 

...but when I do I get an error reading "Server cannot append header after HTTP headers have been sent." (That said, if one clicks F5 through the errors the process is eventually successful and does what is intended serving up a URL line ending in /Details?id=bbb6db33-8f4d-406e-8c3a-9f48008e4608) ...I've read only that this is a fix for the error...

Response.Headers.Clear();

return RedirectToAction("Details", new { id = id } );

 
 

...but it gives me an error about IIS integrated pipeline mode being required. Half our team is running the app in Cassini (including me). Is it just time to get off of Cassini?

.tt in Entity Framework

An .edmx drives our GUI for domain design. Sitting in the same folder there is a .tt file with otherwise the same name which expands to reveal the base objects in POCO form. The naming convention here is Foo.Bar.cs where Foo is the name of the object and Bar is the name of the .edmx and .tt. In the same folder there will also most often be a Foo.cs (for Foo.Bar.cs) which extends Foo for everything it needs beyond a plain old common languague runtime object shape. We call these extensions Partials.

ways to emulate State in the inherently stateless web

  • Cache (bag for all)
  • Session (bag for users)
  • Cookies
  • URL line
  • DOM
  • HTML5 Storage which uses Flash

Monday, August 22, 2011

graph databases

Scott Hanselman speaks to Haixun Wang on Trinity (which is to be Microsoft's Graph Database) in this podcast. We are likely to use a graph database on our project. The most important thing to know, per Mr. Wang, is that the graph database does not use joins which are "expensive." From a point in a graph database, one may find a neighbor without a key join.

We are to have a fascinating dynamicesque feature in our app which will allow users to bolt onto objects custom attributes. While the base objects will be kept in a SQL database, the architects are looking for an alternative approach for the keeping of the custom attributes.

We are more likely to use neo4j for a graph approach. We may also not take a graph approach and take a Cassandra or Redis document database approach instead. The die is not yet cast.

Dunno.

Wikipedia sort of suggests that persisted items expose nodes which have "properties" that one may match against when reaching outward from other persisted items in searching to ultimately make matches to persisted items, grabbing hold by way of nodes (which are almost like the APIs persisted items expose).

simple ref example

doubling 7 to 14 ...will end up in ViewBag.Message given the code below:

public ActionResult Index()

{

   Int32 myNumber = 7;

   ViewBag.Message = DoubleNumber(ref myNumber) + " to " + myNumber;

   return View();

}

   

public string DoubleNumber(ref Int32 growable)

{

   string act = "doubling " + growable;

   growable = growable*2;

   return act;

}

.Any()

.Any() makes sure a List<T> has something in it.

if (myCollection != null && myCollection.Any())

{

What should come back from the Repositories? What shape?

Repository methods should return IQueryable and not IList as the former is, well, queryable. One may reach into it and filter results on the other side of the method call before a trip to the database is every made.

Sunday, August 21, 2011

.OrderBy

This is an example of .OrderBy

var foo = whatever.ToList().OrderBy(x => x.Name);

 
 

Here is a more sophisticated example I found here.

var sorted = model.Products.OrderBy(x => x.ProductName).ThenBy(x=>x.ProductID);

 
 

I found this stuff while trying to sort not a List<T> but instead a PagedList<T>. This suggests there is some bugginess in sorting a PagedList<T>. I find myself struggling to implement .OrderBy on a PagedList itself. I am struggling to figure out what I am supposed to pass in. I also am struggling to figure out how to just cast everything in a PagedList back out to an IEnumerable. Whatever. Maybe I should just message things before passing them into PagedLists and not expect to ever pull stuff back out.

WhatsApp

WhatsApp is an instant messenger app that works well for communicating to team members on different continents. Fu-Han "Mike" Wong recommended it. Get it for the iPhone at the AppStore.

smells like web forms

The most elementary implementation of a form in Razor is going to use as the outbound action the same route that one came into the form on.

@using (Html.BeginForm())

{

in a CRUD app, should the same View "manage" both create and edit?

Is it wise to have the create and update screens in a CRUD app use the same view or is it too painful?

@if(Model.Name != null){

   <input type="submit" value="Edit" />

} else {

   <input type="submit" value="Create" />

}

 
 

Maybe it is more painful not too. What does everyone think?

Saturday, August 20, 2011

use Entity Framework and NHibernate together if you dare!!!

In our app we have a best of both worlds thing going on in which we embrace BOTH Entity Framework and NHibernate. By best of both worlds, I mean that we mostly use NHibernate, but we have wired up the Entity Framework GUI tools to work with NHibernate. A T4 Template generates NHibernate wire ups when an .edmx file is saved. The .edmx file shows a snapshot of how all of our entities interface. Very cool stuff.


 
 

I have not used Entity Framework in a very long time (because no one else does) and I tried to familiarize myself with it anew some today (you may see as much in prior blog postings), and I wrote some notes like this...

  • Right-click in an .edmx's GUI layout and pick "Generate Database from Model..." from the menu that appears to shove a model to a database (you will have to pass through an intermediary step as a SQL script will appear in Visual Studio and you will need to right-click in the SQL script and pick "Execute SQL")

...but I ultimately gave up on trying to spin it up in a new app to really understand it when I started hitting enough obstacles to discourage me. I don't need to know Entity Framework for the project I am on, I just need to understand .edmx files. In them, one may click on associations (to make seletions as shown below) and then right-click to delete an association.


 
 

One may right-click in an .edmx and pick "Add Association..." to craft Associations. By this process, I have, in this example, changed a many-to-many association to a one-to-many association. Notice the change in column name that resulted.


 
 

Employer and Graduate aren't real entities in our app. ;)

Build versus Rebuild

When building a project, the build will also build dependent projects if they are not built, but will not build dependent projects if compiled .dlls already exist. A rebuilt will force a built of all projects "downstream" of a project without regard to whether or not they are built already. Builds will conditionally rebuild in scenarios when Visual Studio is wise to a change in a dependent project too, but this is "dangerous" because this sort of wisdom is seems pretty flaky and unreliable.

camel case and pascal case

Use camel case for private variables in C# but otherwise use pascal case. Private methods in Java use camel case but this convention does not exist for C# per Microsoft.

getting Count from PagedList

foo.TotalItemCount gives the total records of a collection in a IPagedList<T> while
 
foo.Count will be capped at the maximum number of rows in a page if the total count of records exceeds this number.

four random things

  1. Rebuilding our data project will fire the appropriate SQL script to drop and wipe the local database where building the whole of the solution may not. I don't know why right now.
  2. One may run a console application kept in a separate project by right-clicking on the project and selecting: Debug > Start New Instance (I had introduced the ZDataLoader concept of CodeCampServer to our app and it was determined that it would be best if ZDataLoader was not run as a unit test but was instead part of a standalone project for populating data.
  3. Turn off line numbering in Visual Studio 2010 at Tool > Options > Text Editor > All Languages (the same place one sets how many spaces are in tabs)
  4. var foo = TestUtils.BuildTestController(); is preferred to
     
    var foo = new BarController(); in testing as the former allows for mocking HttpContext and Session. This is something that Joel Holder rolled. It is part of our app only.

FormCollection is a code smell

try to use a model instead of FormCollection - FormCollection is a code smell

.AsQueryable()

this post has this example:

List<int> grades = new List<int> { 78, 92, 100, 37, 81 };

IQueryable<int> iqueryable = grades.AsQueryable();

 
 

...which shows how to do casting to an IQueryable with AsQueryable(). The practical application for this comes in mocking. If a repository returns collections in IQueryable format then one will need to use this format for mocking the method call in question in testing. One may new up a List<Foo> in another class, independent of a trip to the database (no such trip required) and then cast the List<Foo> to an IQueryable<Foo>.

a different way to new up

Foo foo = new Foo{ Bar = "baz", Qux = true };

 
 

...is not unlike...

Foo foo = new Foo();

foo.Bar = "baz";

foo.Qux = true;

add an new .edmx

make a new .edmx by adding a new file and browsing to Visual C# > Data > ADO.NET Entity Data Model where Model1.edmx is the default name I suppose

C:\Program Files (x86)\Microsoft SQL Server\MSSQL.1\MSSQL\Data ...contains test.mdf which I want to use. I stepped through the wizard to make the connection and was told that the .mdf was being used by another process. I restarted my laptop and tried again. This ended up in Web.Config:

<add name="testEntities" connectionString="metadata=res://*/Models.Model1.csdl|res://*/Models.Model1.ssdl|res://*/Models.Model1.msl;provider=System.Data.SqlClient;provider connection string="data source=.\SQLEXPRESS;attachdbfilename=|DataDirectory|\test.mdf;integrated security=True;connect timeout=30;user instance=True;multipleactiveresultsets=True;App=EntityFramework"" providerName="System.Data.EntityClient" /></connectionStrings>

connect to local MSSQL database

I think one makes a connection to a local MSSQL database like so:

<add name="ApplicationServices" connectionString="data source=.\SQLEXPRESS;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|test.mdf;User Instance=true" providerName="System.Data.SqlClient" />

 
 

Note the reference directly to an .mdf above. http://www.microsoft.com/express/Database/ is a place to go get the means to run MSSQL locally, I think.

Friday, August 19, 2011

chain together filters on top of repository calls

In C#, using NHibernate and LINQ, one may chain together filters on top of repository calls like so:

fooModel.SetPagedFoo(FooRepository.GetAll().FindAll(FilterSpecs.BarCriteria(filter)).FindAll(FilterSpecs.BazCriteria(filter)));

 
 

The "filter" being passed in is of this object, but isn't what is really interesting...

using System;

using System.Collections.Generic;

using System.Web.Mvc;

using MyApp.Core;

using MyApp.Core.Entities;

using MyApp.Core.Repositories;

using MyApp.Core.Utils;

namespace MyApp.UI.Models

{

   public class FilterParameters

   {

      public IBarRepository BarRepository { get; set; }

      public IBazTypeRepository BazRepository { get; set; }

      

      public Bar bar { get; private set; }

      public Baz baz { get; private set; }

      

      public ProgramFilterParams(FormCollection formCollection)

      {

         BarRepository = ServiceLocator.Get<IBarRepository>(AppCtxIds.BAR);

         BazRepository = ServiceLocator.Get<IBazRepository>(AppCtxIds.BAZ);

         tryToDefineBar(formCollection["baresque"] as string);

         tryToDefineBaz(formCollection["bazesque"] as string);

      }

      

      private void tryToDefineBar(string potentialBar)

      {

         if (!potentialBar.IsNullOrEmpty())

         {

            IEnumerable<Guid> barIds = new Guid[] {new Guid(potentialBar)};

            bar = BarRepository.GetBar(barIds)[0];

         }

      }

      

      private void tryToDefineBaz(string potentialBaz)

      {

         if (!potentialBaz.IsNullOrEmpty())

         {

            IEnumerable<Guid> bazIds = new Guid[] { new Guid(potentialBaz) };

            baz = BazRepository.GetBaz(bazIds)[0];

         }

      }

   }

}

 
 

...the "FilterSpecs" ARE really interesting!

using System.Linq;

using MyApp.Core.Entities;

using LinqSpecs;

using MyApp.UI.Models;

namespace MyApp.UI.Specs

{

   public class FilterSpecs

   {

      public static Specification<Foo> BarCriteria(FilterParameters filter)

      {

         if (filter.bar != null)

         {

            var dateSpec = new AdHocSpecification<Foo>(

                  f => f.Child.Where(c => c.Bar.Id == filter.bar.Id).Count() > 0

               );

            return dateSpec;

         } else {

            var dateSpec = new AdHocSpecification<Foo>(f => f != null);

            return dateSpec;

         }

      }



      public static Specification<Foo> BazCriteria(FilterParameters filter)

      {

         if (filter.baz != null)

         {

            var dateSpec = new AdHocSpecification<Foo>(

                  f => f.Child.Where(c => c.Baz.Id == filter.baz.Id).Count() > 0

               );

            return dateSpec;

         } else {

            var dateSpec = new AdHocSpecification<Foo>(f => f != null);

            return dateSpec;

         }

      }

   }

}

 
 

OK, at the very first line of code at the top of this posting, where we show off chainability of filters, everything is shoved into a method called SetPagedFoo which might look like this...

private IList<Foo> SetPagedFoo(IQueryable<Foo> query = null)

{

   IList<Foo> foos;

   if (query != null)

   {

      foos = query.ToList();

      
more code follows...

 
 

The NHibernate SQL is crafted at the first line of code in this post, but it is not executed until the last line of code above is run. When an IQueryable<Foo> is cast to another type, then and only then does the would be SQL call become an actual trip to the database. This is the magic of IQueryable!

Finally there is a base class for repositories that all of our repositories (such as FooRepository) inheirt from that contains this method:

private IQueryable<T> GetQuery(Specification<T> specification)

{

   var results = Session.Query<T>().Where(specification.IsSatisfiedBy());

   return results;

}

 
 

That is all there is too it!

Serranos


I caught lunch at Serranos today with six of my coworkers, who are, clockwise from my empty seat: Jorge Luna, Joel Holder, Kar-Khan Wai, Komali Uppugandla, Marwane Yazback, and Craig Likes

USE Me;

USE MyDatabaseNameHere; will need to be spliced in at the top of a SQL script generated by this process if you want to be able to right-click on the .sql file in Visual Studio and click "Execute SQL" to run the script.

setup and teardown for testing

namespace MyApp.Data.Tests

{

   [TestClass]

   public class MyTest

   {

      public Foo foo;

      

      [TestInitialize]

      public void TestSetup()

      {

         foo = new Foo();

         foo.Name = "Bar";

         FooRepository.Save(foo);

      }

      

      [TestMethod]

      public void Test()

      {

         Assert.AreEqual(foo.Name,"Bar");

      }

      

      [TestCleanup]

      public void TestTeardown()

      {

         FooRepository.Delete(foo);

      }

   }

}

Trying to get used to MSTest.

Some of our data tests won't work with Resharper so I have to rely on MSTest which I am getting used to. If one does an assert like so...

Assert.IsTrue(unlucky == 13);

 
 

...and the test fails on the assert, one will only see that the test failed (in the "Test Results" pane) on the assert and not what the...

Oh, wait, as I type this I realize that I should really use:

Assert.AreEqual(unlucky,13);

 
 

...as otherwise there is no way to see what the value compared to 13 is when the test fails (Duh) unless one does something like this...

Assert.IsTrue(unlucky == 13, unlucky.ToString());

 
 

The second parameter above is a message to give in the case of a failing test.
Other things to mention...

  1. in the "Test Results" pane, right-click on a test and select "View Test Results Details" to see further specs
  2. one may set breakpoints in a test in Visual Studio and then run the test and stop at the breakpoints... set a breakpoint, and then Ctrl-F+T at the top of the test method to run the test

Alt-Click-Drag

Alt-Click-Drag a selection in Visual Studio to select common things vertically without selecting everything in given lines of code



Addendum 5/9/2013: Alt-Click-Drag should really be Alt-Ctrl-Drag. Hold Alt and Ctrl together to obtain this effect. Drag the mouse while holding the two keys.

 
 

Addendum 9/19/2019: It's back to being Alt-Click-Drag anymore in Visual Studio 2019. You don't hold Ctrl anymore.

Lambda/NHibernate

Trying to figure out Lambda/NHibernate calls today...

[TestMethod]

public void Can_Query_NHibernate_With_DateTime()

{

   var foo = Bar.GetAll().Where(o => o.MyDate > DateTime.Now).ToList();

   Assert.IsTrue(foo.Count > 0);

}

 
 

GetAll(), as given above and below, is explained here.

[TestMethod]

public void Can_Query_NHibernate_With_DateTime()

{

   var foo =

      Bar.GetAll().Where(

         p =>

         p.FirstChild.Where(

            baz =>

            baz.SecondChild.Where(

               qux => qux.MyDate > DateTime.Now

            ).Count() > 0

         ).Count() > 0);

   Assert.IsTrue(foo.Count() > 0);

}

Thursday, August 18, 2011

RedGate SQL Data Compare

  1. Populate your schema with data at a database at SQL Server Management Studio.
  2. Detach the database from Microsoft SQL Server Management Studio. It will end up some place like this:
    C:\Program Files (x86)\Microsoft SQL Server\MSSQL.1\MSSQL\Data
  3. Make a copy of the .mdf and .ldf file.
  4. Reattach the old database and rename it something else.
  5. Attach the new database and get rid of its contents.
  6. Download a trial of Redgate SQL Data Compare 9.0
  7. Install it!
  8. Spin up the app. Compare two databases as shown here and then finally click "Compare Now"
  9. Enter the "Synchronization Wizard" and then with the option for "Create a synchronization script" checked click "Next"
  10. There will be a tab called "Synchronization Script" that holds the SQL you want.

Din Ho Chinese BBQ

My fortune cookie at an outing to a geek lunch at Din Ho Chinese BBQ made me think of test-driven development: All the water in the world can't sink a ship unless it gets inside.

Joel Holder wrote SessionObjectCache which wraps Session

Put object bar into a Session named as variable foo defines:

SessionObjectCache.Add(foo, bar);

 
 

Conditionally retrieve from a Session named as variable foo defines a Bar object:

if (SessionObjectCache.Get(foo) != null) bar = SessionObjectCache.Get<Bar>(foo);

minimize Magic Strings

This is superior to what is given below as it does not identify Session variable by way of a magic string.

string foo = "bar";

string baz = "";

if(Session[foo] != null)

{

   Session[foo] = "qux";

} else {

   baz = Session[foo] as string;

}

 
 

This use of a magic string is a code smell.

string baz = "";

if(Session["bar"] != null)

{

   Session["bar"] = "qux";

} else {

   baz = Session["bar"] as string;

}

What Tests are Failing?

In Team Foundation Server's Team Explorer pane in Visual Studio: Go to... Your project > Builds > Appropriate Build... double-click to open Build Explorer > click on the latest failing build > go to "View Log"

All of the tasks that ran will be listed. Also noted is whether or not the tasks passed or failed.

follow [TestMethod] with [Ignore]

...just to keep the build from breaking until you can figure out what is wrong ;)

Wednesday, August 17, 2011

Mock You!

Our app has MOQ, pronounced "Mock You" in play for mocking. I'm trying to understand it. It doesn't look that tricky.

using System;

using System.Collections.Generic;

using Microsoft.VisualStudio.TestTools.UnitTesting;

using App.Core;

using App.Core.Entities;

using App.UI.Controllers;

using Moq;

using App.Core.Repositories;

using App.Tests;

using System.Web.Mvc;

using App.UI.Tests.Support;

namespace App.UI.Tests

{

   [TestClass]

   public class ProfileControllerTest

   {

      IProfileRepository fakeRepo { get; set; }

      Mock<IProfileRepository> mockProfileRepository { get; set; }

      

      private static string userWithProfile = @"FOO\ProfileExists";

      private static string userWithoutProfile=@"FOO\NoProfile";

      private static Guid userIdForUserWithProfile = System.Guid.NewGuid();

      Profile existingProfile = TestObjects.BuildProfile(userWithProfile);

      Profile newProfile = new Profile() { UserName = userWithoutProfile };

      

      [TestInitialize]

      public void TestSetup()

      {

         existingProfile.Id = userIdForUserWithProfile;

         mockProfileRepository = new Mock<IProfileRepository>();

         mockProfileRepository.Setup(

            repo => repo.GetByUserName(userWithProfile)

            ).Returns(existingProfile).Verifiable();

         mockProfileRepository.Setup(

            repo => repo.GetById(userIdForUserWithProfile)

            ).Returns(existingProfile).Verifiable();

         mockProfileRepository.Setup(

            repo => repo.GetByUserName(userWithoutProfile)

            ).Returns(default(Profile)).Verifiable();

         mockProfileRepository.Setup(

            repo => repo.Save(existingProfile)

            ).Verifiable();

         mockProfileRepository.Setup(

            repo => repo.Save(newProfile)

            ).Verifiable();

         fakeRepo = mockProfileRepository.Object;

         fakeRepo = mockProfileRepository.Object;

         ServiceLocator.LookupSource = () =>

         {

            var testServices = new Dictionary<string, object>();

            testServices[AppCtxIds.PROFILE_REPOSITORY] = fakeRepo;

            return testServices;

         };

      }

      

      [TestMethod]

      public void ProfileDetailsTest()

      {

         //arrange

         var controller = new ProfileController();

         controller.ProfileRepository = fakeRepo;

         

         //act

         var actionResult = controller.Details(userIdForUserWithProfile);

         var viewResult = (ViewResult)actionResult;

         

         //assert

         mockProfileRepository.Verify(

            pr => pr.GetById(userIdForUserWithProfile), Times.Once()

            );

         Assert.IsNotNull(controller.ProfileRepository);

         var viewProfile = ((Profile)viewResult.ViewData.Model);

         Assert.IsTrue(viewProfile.UserName == userWithProfile);

      }

      

      
more code follows...

base class for repositories

This is a fascinating class here. It is abstract, meaning that it cannot be instantiated. It is a base class for our repositories.

using System;

using Spring.Data.NHibernate.Support;

using System.Collections.Generic;

using System.Linq;

using NHibernate.Linq;

using App.Core.Entities;

using LinqSpecs;

using Spring.Transaction.Interceptor;

using System.ComponentModel.DataAnnotations;

namespace App.Data.Storage

{

   public abstract class DataAccessObject<T, TId> : HibernateDaoSupport

   where T : BaseEntity<TId>

   {

      public IQueryable<T> Page(IQueryable<T> query, int page, int pageSize)

      {

         return query.Page<T>(page, pageSize);

      }

      

      public IQueryable<T> FindAll(Specification<T> specification)

      {

         return GetQuery(specification);

      }

      

      public IQueryable<T> GetAll()

      {

         return Session.Query<T>();

      }

      

      public T GetById(TId id)

      {

         return Session.Get<T>(id);

      }

      

      public T Load(TId id)

      {

         return Session.Load<T>(id);

      }

      

      
more core here...

 
 

Repositories inherit from DataAccessObject like so...

using System;

using App.Core.Entities;

using App.Core.Repositories;

namespace App.Data.Storage

{

   public class FooRepository : DataAccessObject<Foo, Guid>, IFooRepository

   {

   }

}

cursor: move;

cursor: move; makes (your cursor) sort of a + symbol with arrows at the ends of the four lines, at least in PC browsers. I was just applying this to draggable column headers.

http://www.w3schools.com/cssref/pr_class_cursor.asp gives a good cheatsheet on cursors.

We are using jQuery UI's draggable for this. I like it.

Tuesday, August 16, 2011

Does anyone know how to replace this HTML markup with Razor syntax?

Does anyone know how to emulate this behavior with Razor syntax? I need the blank field, but what is more, I need the blank field to stay around as an option once a match is made.

<select id="Foo" name="Foo">

   <option value="">

   @foreach (var item in FooGetter.GetAll())

   {

      if (FooOfTheMoment == item.Id)

      {

         <option value="@item.Id" selected>@item.Name</option>

      } else {

         <option value="@item.Id">@item.Name</option>

      }

   }

</select>

newing up IEnumerable

Just because this works...

List<Guid> foo = new List<Guid>() {new Guid(bar)};

 
 

Does not mean that this works...

IEnumerable<Guid> foo = new IEnumerable<Guid>() {new Guid(bar)};

 
 

Instead do this...

IEnumerable<Guid> foo = new Guid[] {new Guid(bar)};

using ServiceLocator in a model

Here is an example of using ServiceLocator in a model:

using Something.SomethingElse;

namespace Whatever

{

   public class Foo

   {

      public IBarRepository BarRepository { get; set; }

      public IBazRepository BazRepository { get; set; }

      

      public Foo()

      {

         BarRepository = ServiceLocator.Get<IBarRepository>(AppCtxIds.BAR);

         BazRepository = ServiceLocator.Get<IBazRepository>(AppCtxIds.BAZ);

         CurrentTime = DateService.Now();

      }

      

      public Foo(DateTime myTime)

      {

         CurrentTime = myTime;

      }

      

      
More code here...

 
 

In our code base, one has to have...

  1. Public get/setters for repositories
  2. Parameterless constructors for instantiation (I don't fully understand why as of yet)

 
 

The different constructor here is for testing a specific time value from two unit tests that will not need the repositories.

when to use @ after @

Don't use the at symbol to declare Razor markup after you have already used it...

@if (Something... something...

{

   if (
Something... something...

   {

 
 

UNLESS you have made your way out of Razor markup and need to make your way back into it.

@if (Something... something...

{

   <p><text>Hello World</text></p>

   @if (
Something... something...

   {

Is something not assigned to you in "My Assigned Tasks" in TFS?

Go into the grocery list for the Sprint, double-click on the item, assign the item to yourself. It will then make sense for you to log time against the item in Team Foundation Server.

faking a FormCollection for testing seems easy enough

using System.Web.Mvc;

using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace AMD.Avalanche.Web.UI.Tests.Model

{

   [TestClass]

   public class Foo

   {

      [TestMethod]

      public void Bar()

      {

         FormCollection formCollection = new FormCollection();

         formCollection["FilterTimeRange"] = "FilterTimeRange";

         string somethingBackFromTheFormCollection = formCollection["FilterTimeRange"];

         Assert.AreEqual(somethingBackFromTheFormCollection, "FilterTimeRange");

      }

   }

}

Monday, August 15, 2011

App_Code helpers and "Helpers" folder helpers

App_Code helpers should like this:

@FormHelpers.Whatever("foo");

 
 

In this case there will be a FormHelpers.cshtml file in the App_Code folder and it will have inside of it something like:

@helper Whatever(string css = ""){

   <input type="submit" value="submit" class="@css" />

}

 
 

There may be many little items like this collected in FormHelpers.cshtml.

A "Helpers" folder helper looks more like this.

using System.Web;

using System.Text;

public static class MyHtmlHelper

{

   public static IHtmlString Whatever(string css)

   {

      var sb = new StringBuilder();

      sb.Append("<input type='submit' value='submit' class='");

      sb.Append(css);

      sb.Append("' />");

      return new HtmlString(sb.ToString());

   }

}

 
 

One calls a "Helpers" folder helper like so:

@Html.Whatever(foo)

less abstraction and more Razor

I replaced this...

@{Html.RenderPartial("_MyPartial", Category.GetAll());}

 
 

...with this...

@Html.DropDownList("SampleCategory", new SelectList(Category.GetAll(), "Id", "Name"),

   "", new Dictionary<string, object>

   {

      {"class", "select01"}

   })

 
 

...in the name of LESS abstraction and MORE Razor. (Note above that the double quotes with nothing inside of them defines the first value of the dropdown list, a blank value.) The partial originally referenced looked like so:

@model IEnumerable<MyApp.Core.Entities.Category>

<select class="select01" name="SampleCategory">

   <option value="" selected></option>

   @foreach (Category category in Model)

   {

      <option value="@category.Id">@category.Name</option>

   }

</select>

 
 

Still getting used to Razor dropdown lists? Here is a good cheatsheet.

Craig and Byron

Craig Likes wrote type extension methods not Byron Lousiq-Nont.

But they are both awesome.

PagedList

Got some PagedList<T> going on... cool stuff...

var whatever = Whatever.ToPagedList(whichPage, recordsPerPage);

Debug - skip data tests

We have a way on our project to change from "Debug" mode to "Debug - skip data tests"

Data test inheirts from DataIntegrationTestBase which inheirts from AbstractTransactionalSpringContextTests

I don't have time right now to figure out how "Debug - skip data tests" was created and implemented.

Sunday, August 14, 2011

Trying to understand Reflection and Attributes

I am, as the name of this blog implies, trying to understand Reflection and Attributes. I am tinkering around with the app I made here, refined here, and further messed about with here. I decided I wanted to add some polymorphism so that this method doesn't have to have an array of Address passed into it.

public void PrepModel(Person person, Address[] newHomes)

{

   Name = person.Name;

   BirthDay = person.BirthDay.Month.ToString();

   BirthDay = BirthDay + "/" + person.BirthDay.Day;

   BirthDay = BirthDay + "/" + person.BirthDay.Year;

   Age = person.Age.ToString();

   HomeCollection = new Dictionary();

   foreach (Address address in newHomes)

   {

      HomeCollection.Add(address.Id, address.Street);

   }

   Home = person.Home.Id.ToString();

}

 
 

Instead, a method with one parameter can grab Addresses from another source and in this case I'll use reflection to get what I want just to be complicated.

public void PrepModel(Person person)

{

   Name = person.Name;

   BirthDay = person.BirthDay.Month.ToString();

   BirthDay = BirthDay + "/" + person.BirthDay.Day;

   BirthDay = BirthDay + "/" + person.BirthDay.Year;

   Age = person.Age.ToString();

   HomeCollection = new Dictionary();

   AddressAssignmentModel dummyModel = new AddressAssignmentModel();

   dummyModel.trySettingAttribute();

   Type type = typeof(AddressAssignmentModel);

   foreach (MethodInfo method in type.GetMethods())

   {

      object[] attributes = method.GetCustomAttributes(typeof(AddressAttribute), false);

      foreach (Object attribute in attributes)

      {

         AddressAttribute addressAttribute = attribute as AddressAttribute;

         if (null != addressAttribute)

         {

            foreach(Address address in addressAttribute.newHomes)

            {

               HomeCollection.Add(address.Id, address.Street);

            }

         }

      }

   }

   Home = person.Home.Id.ToString();

}

 
 

Alright, AddressAssignmentModel looks like what you see here. I couldn't get my process to work until I put [Address(true)] on a new method and called it instead of using it on my constructor. Maybe constructors are not seen as methods.

using MyApp.Helpers;

namespace MyApp.Models

{

   public class AddressAssignmentModel

   {

      public AddressAssignmentModel()

      {

      }

      

      [Address(true)]

      public void trySettingAttribute()

      {

      }

   }

}

 
 

AddressAttribute looks like this:

using Core;

namespace MyApp.Helpers

{

   using System;

   [AttributeUsage(AttributeTargets.All)]

   public class AddressAttribute : System.Attribute

   {

      public readonly Address[] newHomes;

      

      public AddressAttribute(bool shouldPopulateAddresses)

      {

         if (shouldPopulateAddresses)

         {

            Address austin = new Address();

            austin.Id = new Guid("75b5e18c-13c5-4211-bf8d-9f3d0117d88c");

            austin.Street = "1507 Houston Street #145";

            austin.ZipCode = 78756;

            

            Address haverhill = new Address();

            haverhill.Id = new Guid("bb61cd17-c176-4102-838a-9f3d0117d892");

            haverhill.Street = "5055 Club Road";

            haverhill.ZipCode = 33415;

            

            Address houston = new Address();

            houston.Id = new Guid("31ba86cb-991f-4e71-a2df-9e4000a8b3bc");

            houston.Street = "14795 Memorial Drive";

            houston.ZipCode = 77079;

            

            Address lampasas = new Address();

            lampasas.Id = new Guid("d74e7f2c-ad8d-4522-bb1e-9f3d0117d895");

            lampasas.Street = "1006 East Avenue F";

            lampasas.ZipCode = 76550;

            

            newHomes = new Address[] { austin, haverhill, houston, lampasas };

         } else {

            newHomes = new Address[] { };

         }

      }

   }

}

Flattening!

I'm messing around with AutoMapper and trying to figure out how to make it flatten across two one-to-many relationships (i.e. parents, children, and grandchildren collapsed into one flat format) instead of just one... but I'm not going to be able to figure it out this morning. I'm sleepy from being up all night. I thought I'd give a posting that is just a quick overview of AutoMapper and then leave AMD as the sun comes up. It's time for IHOP. Anyways... I’m "expanding" upon the code base in this posting and this posting too. I have replaced this line in the Person object...

public Address Home { get; set; }

 
 

...with this line...

public Address[] Homes { get; set; }

 
 

...my Controller now looks like so...

using System;

using System.Web.Mvc;

using Core;

using MyApp.Models;

namespace MyApp.Controllers

{

   public class HomeController : DefaultController

   {

      public ActionResult Index()

      {

         Address austin = new Address();

         austin.Id = new Guid("75b5e18c-13c5-4211-bf8d-9f3d0117d88c");

         austin.Street = "1507 Houston Street #145";

         austin.ZipCode = 78756;

         

         Address haverhill = new Address();

         haverhill.Id = new Guid("bb61cd17-c176-4102-838a-9f3d0117d892");

         haverhill.Street = "5055 Club Road";

         haverhill.ZipCode = 33415;

         

         Address houston = new Address();

         houston.Id = new Guid("31ba86cb-991f-4e71-a2df-9e4000a8b3bc");

         houston.Street = "14795 Memorial Drive";

         houston.ZipCode = 77079;

         

         Address lampasas = new Address();

         lampasas.Id = new Guid("d74e7f2c-ad8d-4522-bb1e-9f3d0117d895");

         lampasas.Street = "1006 East Avenue F";

         lampasas.ZipCode = 76550;

         

         Address[] addresses = new Address[] {austin, haverhill, houston, lampasas};

         

         Person person = new Person();

         person.Id = new Guid("705b5d2b-6bed-4d6d-af29-9e4000a8b25e");

         person.Name = "Tom";

         person.setBirthDay(new DateTime(1974, 8, 24));

         person.Homes = addresses;

         

         return AutoMapView<PersonShowModel>(View(person));

      }

   }

}

 
 

...my View Model looks like so...

using System;

namespace MyApp.Models

{

   public class PersonShowModel

   {

      public string Name { get; set; }

      public DateTime BirthDay { get; set; }

      public int Age { get; set; }

      public AddressModel[] Homes { get; set; }

      

      public class AddressModel

      {

         public string Street { get; set; }

         public Int32 ZipCode { get; set; }

      }

   }

}

 
 

...and the View itself looks like so...

@model MyApp.Models.PersonShowModel

<table>

@foreach (var item in Model.Homes)

{

   <tr>

      <td>@Model.Name</td>

      <td>@Model.Age</td>

      <td>@Model.BirthDay</td>

      <td>@item.Street</td>

      <td>@item.ZipCode</td>

   </tr>

}

</table>


 
 

OK. What are the steps to wire this up?

  1. Add a reference to the AutoMapper .dll

     
     

  2. In Application_Start() in Global.asax.cs put:

    AutoMapperBootstrapper.Initialize();

     
     

  3. Create a "Helpers" folder if you do not yet have one.

     
     

  4. Put <add namespace="MyApp.Helpers"/> in the </namespaces> portion of Web.config if it is not yet there. (this namespace trick may be what Byron is utilizing here/see the last paragraph)

     
     

  5. AutoMapperViewResults.cs (one of two files that you must create in the Helpers folder) is going to look like this:

    using System;

    using System.Web.Mvc;

    using AutoMapper;

    namespace MyApp.Helpers

    {

       public class AutoMapViewResult : ActionResult

       {

          public Type SourceType { get; private set; }

          public Type DestinationType { get; private set; }

          public ViewResultBase View { get; private set; }

          

          public AutoMapViewResult(Type source, Type dest, ViewResultBase view)

          {

             SourceType = source;

             DestinationType = dest;

             View = view;

          }

          

          public override void ExecuteResult(ControllerContext context)

          {

             var model = Mapper.Map(View.ViewData.Model,

                SourceType,

                DestinationType

                );

             View.ViewData.Model = model;

             View.ExecuteResult(context);

          }

       }

    }

     
     

  6. AutoMapperBootstrapper.cs (the other file that you must create in the Helpers folder) is going to vary from application to application. In this case it looks like this:

    using AutoMapper;

    using Core;

    using MyApp.Models;

    namespace MyApp.Helpers

    {

       public static class AutoMapperBootstrapper

       {

          public static void Initialize()

          {

             Mapper.Initialize(cfg =>

             {

                cfg.AddProfile<PersonShowModelProfile>();

             });

          }

       }

       

       public class PersonShowModelProfile : Profile

       {

          protected override void Configure()

          {

             CreateMap<Person, PersonShowModel>();

             CreateMap<Address, PersonShowModel.AddressModel>();

          }

       }

    }

     
     

  7. Here is another great example of extending MVC. If AutoMapViewResult is bright red in Visual Studio it means that you are still inheriting from Controller at your Controller instead of DefaultController which is a new file that you will need which looks like this:

    using System.Web.Mvc;

    using MyApp.Helpers;

    namespace MyApp.Controllers

    {

       public class DefaultController : Controller

       {

          protected AutoMapViewResult AutoMapView<TDestination>(

             ViewResultBase result

             )

          {

             return new AutoMapViewResult(

                result.ViewData.Model.GetType(),

                typeof(TDestination), result

                );

          }

       }

    }

     
     

  8. The only other thing I can think to mention is a curious problem that is touched on at the bottom of the comments on this post by Matt Hinze where Matt refers the individual asking over to this post by Jimmy Bogard. The problem is of seeing this error:

    The model item passed into the dictionary is of type 'Something' but this dictionary requires a model item of type 'SomethingElse'.

    For me, the issue had nothing to do with AutoMapper. I had simply screwed up the model binding in a View while incorporating AutoMapper. I had a Controller handing in one model and the View trying to consume a different model. This mistake causes this error. I jumped to the conclusion that the problem was of AutoMapper, but if you have this problem you may want to take another look.