# Monday, February 06, 2012

I have been working a lot with MVC sites lately and experimenting with how to make them *usable* on mobile browsers.  This is post is about the single line of mark-up you can add to your sites Master Page, or in this case your _Layout.cshtml.

Before I get to that line I am going to show you a quick screen shot of a vanilla MVC 3 application, that can be downloaded here.

First is a screen shot of the site running in a desktop browser.



Next, is the site rendered on Windows Phone 7, Android, and iPhone.

Windows Phone 7

Opera Mobile (Android)


image image image


The first thing you notice is that iOS does a fairly good job adaptively rendering the site, damn Apple!  Next you will notice that all WP7 and Android do is zoom out so the site fits on the device.  A site of any significant content or functionality would be almost useless because of the amount of panning and zooming that would be required.  I am sure we have all dealt with sites on our mobile devices like that.  So what can we do to make the site render better in WP7 and Android?

You can actually get a long way towards perfect mobile rendering of your site by adding one simple html tag.

  1. <meta name="viewport" />

The meta viewport tag can be used to control how HTML content is displayed in mobile browsers.  The meta viewport tag has properties like width, height, minimum-scale, and maximum-scale.  In this example the particular property we are concerned with is the width property.  We want to tell the the browser to render our content width at the width of device.

  1. <meta name="viewport" content="width=device-width">

Let’s see what happens when we add that tag to the head of our _Layout.cshtml file


As you can see above, because the meta viewport tag only effects mobile browsers our desktop version looks exactly the same.  Let’s check on the mobile browsers.

Windows Phone 7

Opera Mobile (Android)


image image image

The site looks much better on Windows Phone 7 and Android, and still looks the same in Apple.  So by adding that single line of mark-up we where able to give our mobile users a much better user experience.

Stay tuned for a future post on using CSS Media Queries to improve the mobile experience even further.

posted on Monday, February 06, 2012 8:15:38 AM (Central Standard Time, UTC-06:00)  #    Comments [2]
# Monday, January 30, 2012

The var keyword was introduced with C# 3.0 and the .NET Framework 3.5 to allow the declaration of implicitly typed variables.  The driving force behind the need for implicitly typed variables was the introduction of Anonymous Types

If you are using var outside of truly anonymous types you are doing so out of laziness.  I know this is a bold statement that a lot of developers are going to disagree with, so let me explain.

First off I totally agree that using var can speed up your lines per minute coded and I do use var in this manner.  But, I always replace var with the actual type after the fact.  You can do this with out requiring a large amount of time after the fact using a tool such as ReSharper and setting up you Clean Up Code” functionality to replace all usages of var with the actual type when possible.

Now for my supporting arguments:  *All of which only pertain to using var when the type is not truly anonymous.*

  • C# is not a Dynamic Language!  This may be bad or not ideal but it is fact.  The truth is not everyone is fluent in dynamic languages and they are not expecting to read code coded in a dynamic fashion when dealing with C#.
  • Code written in a dynamic fashion, i.e. implicitly typed , is harder to read, especially when you are not use to reading it.  I know what you are saying how is this hard to read?:
    1. var x = "This is not hard to read and understand what x is!";

    And you are correct, that example is not hard to read and figure what x is.  What about this?
    1. var x = from custs in dataContext.Customers
    2.         join orders in dataContext.Orders
    3.             on custs.CustomerId equals orders.CustomerId
    4.         join lines in dataContext.OrderLines
    5.             on orders.OrderId equals lines.OrderId
    6.         join products in dataContext.Products
    7.             on lines.ProductId equals products.ProductId
    8.             where products.Name.Contains("FooBar")
    9.         where custs.LastName.Contains("Smith")
    10.         select products

    I would much rather see and read;
    1. IQueryable<Product> x = from custs in dataContext.Customers
    2.                         join orders in dataContext.Orders
    3.                             on custs.CustomerId equals orders.CustomerId
    4.                         where custs.LastName.Contains("Foo")
    5.                         join lines in dataContext.OrderLines
    6.                             on orders.OrderId equals lines.OrderId
    7.                         where lines.Quantity > 10
    8.                         join products in dataContext.Products
    9.                             on lines.ProductId equals products.ProductId
    10.                         where products.Name.Equals("FooBar")
    11.                         where custs.LastName.Contains("Smith")
    12.                         select products;

              The truth is you know what your result is, at least you better or you have no business writing the code in the first place, so just declare it as such!

              One more thing,  var has no place in demo code, tutorials, and blog posts. The purpose of demo code, tutorials, and blog posts are to provide education and in doing so the code should be clean and concise and accessible to the masses.

              OK, let me have it.

              posted on Monday, January 30, 2012 10:00:02 AM (Central Standard Time, UTC-06:00)  #    Comments [12]
              # Monday, January 23, 2012

              Support for spatial data was introduced in SQL Server 2008.  What this allows you to do is capture data related to 2D geometric or geographical images in SQL Server.  It actually allows you to do much more than just storing a bunch of numbers representing this data.  In the initial releases of Entity Framework the spatial data type was not available for use, but with the Entity Framework June 2011 CTP release this functionality is now available.

              I am once again working with the code from my Entity Framework Code First Demo post.  This simple application is dream car tracker that tracks manufacturers and models of cars that someday I would love to own.  As part of the manufacturer data I currently store the Country but would like to be able to map out the corporate headquarters for the day when I get to take a trip and take delivery.  I am able to retrieve the latitude and longitude from Google Maps by knowing the address.

              The Ferrari factory located at: Via Abetone Inferiore n. 4, I-41053 Maranello Italy has a latitude and longitude of 44.53244, 10.86412.  At this point if you are new to the spatial data type, like I was, you are probably thinking “that is just a decimal and you could always store decimals in SQL Server” and you are correct.  I could certainly just add two decimal properties to my model that represent latitude and longitude and go on my merry way but using spatial data functionality introduced in the June CTP I get so much more.

              Because I am dealing with geographical data and not geometric data I am going to use the DbGeography type, that can be found in System.Data.Spatial, and add a Location property to my Manufacturer model.

              1. public class Manufacturer {
              3.     public long ManufacturerId { get; set; }
              5.     [Required]
              6.     [StringLength(40)]
              7.     public string Name { get; set; }
              9.     [Required]
              10.     [StringLength(40)]
              11.     public string Country { get; set; }
              13.     [Required]
              14.     public DbGeography Location { get; set; }
              16.     #region << Navigation Properties >>
              18.     public virtual IList<Model> Models { get; set; }
              20.     #endregion
              22. }

              Once I have Entity Framework Code First regenerate my database I can take a look and see that the .NET Framework type DbGeography translates to the SQL Server type Geography.


              Now that I have my property I can populate the Location data by converting my latitude and longitude values to a DbGeography using the static parse method.  I can add this to my SeedManufacturer method.

              1. private void SeedManufacturer(DataContext context) {
              2.     _ferrari = new Manufacturer {Name = "Ferrari", Country = "Italy"};
              3.     _lamborghini = new Manufacturer {Name = "Lamborghini", Country = "Italy"};
              4.     _astonMartin = new Manufacturer {Name = "Aston Martin", Country = "United Kingdom"};
              5.     _porsche = new Manufacturer {Name = "Porsche", Country = "Germany"};
              6.     _ferrari.Location = DbGeography.Parse("POINT(44.53244    10.86412)");
              7.     _lamborghini.Location = DbGeography.Parse("POINT (44.65934    11.12693)");
              8.     _astonMartin.Location = DbGeography.Parse("POINT (52.18708    -1.48351)");
              9.     _porsche.Location = DbGeography.Parse("POINT (48.83498    9.15231)");
              10.     new List<Manufacturer> {_ferrari, _lamborghini, _astonMartin, _porsche}.ForEach(x => context.Manufacturers.Add(x));
              11. }

              Now if you look at the data in SQL Server you an see that the data is now represented as a nasty looking hex.


              I know you are still wondering what the point is, pun intended!  Well, now I can get to the cool part.  I can use the methods that come along with DbGeography to do things such as getting distance between two manufacturers as illustrated below in line 3.

              1. Manufacturer ferrari = dc.Manufacturers.First(x => x.Name == "Ferrari");
              2. Manufacturer lamborghini = dc.Manufacturers.First(x => x.Name == "Lamborghini");
              3. double distanceInKilometers = ferrari.Location.Distance(lamborghini.Location);
              4. double distanceInMiles = distanceInKilometers/1609.344;
              5. string outputText = string.Format("{0} is {1} miles from {2}", ferrari.Name, distanceInMiles, lamborghini.Name);

              You can also use the methods in LINQ.  The query below finds all the manufacturers that are within a 100 mile radius of my house.

              1. DbGeography myHouse = DbGeography.Parse("POINT (4.65934    1.12693)");
              2. IList<Manufacturer> closeToMe = manufacturers.Where(x => (x.Location.Distance(myHouse)*.00062) <= 100).ToList();
              posted on Monday, January 23, 2012 8:30:40 AM (Central Standard Time, UTC-06:00)  #    Comments [3]
              # Monday, January 16, 2012

              I will be talking about ASP.NET MVC4 and jQuery Mobile at Visual Studio Live! Las Vegas in March.

              Reach the Mobile Masses With ASP.NET MVC 4 and jQuery Mobile

              Creating web applications that will target multiple devices and platforms has become the web developers Holy Grail. Simple HTML pages render without issue no matter what browser or device they are viewed on but who codes simple HTML pages? What happens when you have a business need to hit all mobile platforms?

              You don't have to writes hundreds of lines of code to make this happen! In this talk Keith will show how using the latest version of ASP.NET MVC, MVC4, and JQuery you can develop web applications that target iPhone, iPad, Android, Windows Phone 7, and even Blackberry and not have to code and style each platform separately.

              You will learn:

              • How to make your site "viewable" on most user platforms with minimal effort.
              • How to make your site as usable on all mobile platforms as it is on the desktop browser.
              • How to do all of this without writing code to target each mobile platform independently.

              If you register with my special speaker priority code: VLSPK6 you will save $500 off!

              Visual Studio Live Las Vegas

              Mirage Resort & Casino

              March 26-30, 2012

              Event web site: http://vslive.com/lasvegas

              Twitter: http://twitter.com/vslive - #vslive

              Facebook: http://www.facebook.com – Search “vslive”

              LinkedIn: http://www.linkedin.com - - JOIN “vslive” GROUP

              Visual Studio Live is five days of practical, Microsoft-supported training for developers to help solve your tough .NET development challenges. You'll find how-to advice and the tips and tricks that you'll be ready to implement as soon as you get back to the office. Our expert faculty - including many Microsoft instructors - makes each session interactive so you can discuss your particular development roadblocks and come away with actionable solutions.

              Visual Studio Live Las Vegas offers in-depth training in:

              • Cloud Computing
              • Cross Platform Mobile
              • Data Management
              • HTML5
              • Silverlight / WPF
              • Visual Studio 2010+/.NET 4+
              • Web
              • Windows 8/WinRT
              • Windows Phone 7

              Visual Studio Live Las Vegas – Expert Solutions for .NET Developers

              posted on Monday, January 16, 2012 2:35:00 PM (Central Standard Time, UTC-06:00)  #    Comments [3]
              # Monday, January 09, 2012

              The most requested feature for Entity Framework has been Enum support for a very long time.  At TechEd this year it was announced that Enums would be supported in the next version of the Entity Framework and in June the Entity Framework June CTP was released with Enum support as well some other enhancements.

              In the past I dealt with Entity Framework not supporting Enum by having an int property on my model that represented the Enum’s id.  My model also had a property of the Enum type that was marked as ignored so that EF did not try create a database column for the property.  The setter of the property would set the Enum id field and the getter would convert the Enum id field to the Enum type and return it.  If you are confused by that statement, like me, see the code below.

              1. public class Model {
              3.         public long ModelId { get; set; }
              5.         [Required]
              6.         [StringLength(50)]
              7.         public string Name { get; set; }
              9.         [Required]
              10.         public int Year { get; set; }
              12.         [Required]
              13.         public decimal BasePrice { get; set; }
              15.         public int EngineLocation { get; set; }
              17.         public EngineLocationType EngineLocationType {
              18.             get { return (EngineLocationType) EngineLocation; }
              19.             set { EngineLocation = (int) value; }
              20.         }
              22.         #region << Navigation Properties >>
              24.         public long ManufacturerId { get; set; }
              25.         public virtual Manufacturer Manufacturer { get; set; }
              27.         public virtual IList<Engine> AvailableEngines { get; set; }
              29.         #endregion
              31.     }
              1. public class DataContext : DbContext {
              3.         public DataContext() : base("name=EFCodeFirst") {}
              5.         public IDbSet<Manufacturer> Manufacturers { get; set; }
              6.         public IDbSet<Model> Models { get; set; }
              7.         public IDbSet<Engine> Engines { get; set; }
              9.         protected override void OnModelCreating(DbModelBuilder modelBuilder) {
              10.             modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
              11.             modelBuilder.Entity<Model>().Ignore(x => x.EngineLocationType);
              12.             modelBuilder.Entity<Model>().HasMany(x => x.AvailableEngines).WithMany(x => x.AvailableOn).Map(x => x.MapLeftKey("ModelId").MapRightKey("EngineId").ToTable("ModelEngine"));
              13.             base.OnModelCreating(modelBuilder);
              14.         }
              15.     }

              This gets the job done and really isn’t that messy, but with the new Enum support in the June CTP I can make things cleaner.  To make use of the new Enum support all I have to do is declare a property of EngineLocationType in my model and EF will make all the connections for me.

              1. public class Model {
              3.         public long ModelId { get; set; }
              5.         [Required]
              6.         [StringLength(50)]
              7.         public string Name { get; set; }
              9.         [Required]
              10.         public int Year { get; set; }
              12.         [Required]
              13.         public decimal BasePrice { get; set; }
              15.         public EngineLocationType EngineLocation { get; set; }
              17.         #region << Relationships >>
              19.         public long ManufacturerId { get; set; }
              20.         public virtual Manufacturer Manufacturer { get; set; }
              22.         public virtual IList<Engine> AvailableEngines { get; set; }
              24.         #endregion
              27.     }

              So that is the new EF Enum support.  The only issue I have with the implementation is that ideally I would like to be able to have an EngineLocationType table in my database that Entity Framework would create and populate based on my Enum definition and assign a foreign key relationship to EngineLocation on my Model entity.  That would make the entire process complete and architecturally sound IMHO.

              If you are looking for a code download this is part of the Entity Framework Code First Demo that I did in a previous blog post and the code is available on GitHub.

              posted on Monday, January 09, 2012 8:18:40 AM (Central Standard Time, UTC-06:00)  #    Comments [3]