Thursday, November 26, 2015

Resetting migrations when using Code First Migrations in MVC

  1. Delete all the migrations folder in your project except Configuration.cs
  2. Move Configuration.cs to some place safe and remove from the migrations folder
  3. Delete the records in the __MigrationHistory table in your database
  4. Then run the following command in the Package Manager Console:
    >Enable-Migrations -EnableAutomaticMigrations -Force
    NOTE: This will recreate your Configuration.cs
  5. Replace the new Configuration.cs with the Configuration.cs that we moved to a safe place earlier
  6. Then run the following command in the Package Manager Console:
    >Add-Migration Reset
    NOTE: The name is not important
  7. This will create a file in the migrations folder.
  8. Open the new migration file and comment out all the code in the Up() method such that the body of the method is just commented out code.
  9. Save and Build the project
  10. Then run the following command in the Package Manager Console:
    >Update-Database
  11. Uncomment the Up() method.
  12. Save and Build the project.



Essential MVC Tools

Below is a list of tools, plug-ins, packages, etc that you should really consider using if you are doing development for ASP.NET MVC.

Sidewaffle - custom templates. Can consume them from library or create own

Glimpse - amazing view into all things. particularly performance. Scott Hanselman has a good review of it.

ZenCoding - very cool html coding that greatly reduces typing of html tags

Web Essentials - extends Visual Studio, including design time edit from browser

Less - gives variables, etc to CSS like files that we can generate css files from automatically

WURFL - on nuget for reliable device detection (mobile, table, google glasses, etc)

Automapper - Copying data automatically from object to another similar object








d
dd

Good Articles on MVC and .NET

Getting Started

Implementing Basic CRUD Functionality with the Entity Framework in ASP.NET MVC Application - Good step by step tutorial for MVC 5 (not MVC 6). It also shows how to use TryUpdateModel to specify what can be bound to each object. This is a bit cleaner and more object specific, but does require a bit of code.

Binding 

ASP.NET MVC - The Features and Foibles of ASP.NET MVC Model Binding - a great post that gives an in-depth explanation of  how the binder works and how it can be extended.

Prefixing Input Elements Of Partial Views With ASP.NET MVC - Explains how to make a partial view generate html with references that the Binder can understand properly. Also shows a generic method for passing the prefix to the Partial View. It doesn't say it, but creating Edit Templates and EditorFor() instead of Partial Views will also solve this problem.

Model Binding To A List - Explains how to set the Name html form property so that the binder will create the collection.

Mass Assignment / Over-posting

6 Ways To Avoid Mass Assignment in ASP.NET MVC - If you use the Include or Exclude parameters with the Bind attribute it doesn't seem so say it anywhere, but the names of the fields are the same as what show up in Request.Form. So, things like Person.Address.Name, Person.Address.ID, and Person.Address would all need to be added to the Include parameter in order for fields bound to related objects to be allowed through the Include() list and be added to the Request.Form colletion.

Sharing Create / Edit Screens

 ASP.NET MVC - using the same form to both create and edit - forum on how this could be implemented

View Model

How to Use ViewModel with ASP.NET MVC - shows how to implement the repository pattern, how to organize your project, and how to use a View Model.

Videos

Building Applications in ASP.NET MVC 4  - very in depth video on how to build MVC applications. Most of it still applies to MVC 6. It has details on certain topics that are not covered in the MVC 5 version of the video.

Building Applications in ASP.NET MVC 5 - very good video and in depth video on how to build MVC applications.

Best Practices

Best Practices for ASP.NET MVC  - this is a bit old, from 2010, but still has some good advise.
 

Dependency Injection

Dependency Injection and Unit Of Work using Castle Windsor and NHibernate - good example of how to use DI and UOW in MVC application. It shows NHibernate, but it can be used for Entity Framework. It also shows how to use in the context of the different layers of an application.

Castle Windsor Tutorial 1 - I highly recommend reviewing this tutorial. It shows how to create a Castle Windsor container application. It is complex enough to see how a whole application can be done with only calling the container 3 times. It also found it useful to modify the code such that it does NOT use IoC (i.e. not using Castle Windsor). This involves instantiating objects by hand. Then a line at a time, I removed the code I added to hardcode the creation of an object and added the appropriate line in the Installer for that object. Run the application between changes to see how the container actually instantiates the objects automatically once they are registered (in the installer).

Castle Windsor Tutorial 2 - In the case where you do need to create your own instances of an object and still use IoC, you should use TypedFactoryFacility.

Krzysztof Koźmic on software - talks about IoC concepts in depth.

What's New

Top 10 Changes in ASP.NET 5 and MVC 6

Entity Framework

Configuring Relationships with the Fluent API i.e. configuring Cascade delete and one-to-one relationships.

Unit Testing

Testing Entity Framework with a MOQ - step by step instructions on how to test the EF6+ using MOQ. I am using the latest EF6 and did NOT have to change the class the inherits from DbContext such that the DbSets are virtual because they are already that way in the T4 templates.Also, if you need to access the .Set method of the DbContext then you will need to tell the mock what it should be returning using something like: mockContext.Setup(m => m.Set()).Returns(mockSet.Object); See here for more details.

Attributes for MSTesting - includes samples of attributes for setup and cleanup methods that apply to tests, classes, assemblies, etc depending on the scope you need. A class can be created that has assembly specific setup and cleanup and doesn't need to have any tests actually in the class itself. Teh class does need to be marked as TestClass() though.

Unit Testing Good Patterns #3 - Know Your Moq Argument Matchers - this is an excellent read to understand how to use the It and Verify classes.

Keeping up

Code Magazine

Entity Framework Team Blog

Wednesday, November 25, 2015

Using CDN (Content Delivery Networks) with ASP.NET MVC

CDN (Content Delivery Networks) can be a great way to speed up your ASP.NET MVC application for the following reasons:
  • Files are downloaded from the best geographical location
  • CDN networks are trusted and built for high availability and high usage
  • The browser can download files from several servers at the same time.
  • CDN networks can use caching to further improve performance
With ASP.NET MVC  we can specify a CDN to use AND also a fallback url in the event that the CDN is not available for some reason.

In BundleConfig.cs you can specify a CDN (Content Delivery Networks) url and a fallback url (on web app) if the CDN fails for some reason. The failure is determined on the browser side by checking a javascript expression specified by CdnFallbackExpression.

Here is an example of what can be done for the ~/bundles/query that is set by default on a new project.

            // use CDN if it is available.
            // NOTE: Won't show on local machine unless turn debugging off in web.config
            bundles.UseCdn = true;

            var bundle = new ScriptBundle("~/bundles/jquery",
                @"//cdnjs.cloudflare.com/ajax/libs/jquery/1.10.2/jquery.min.js");
            bundle.CdnFallbackExpression = "window.jquery";
            bundle.Include("~/Scripts/jquery-{version}.js");
            bundles.Add(bundle);

 
Be sure to set the bundles.UseCdn = true. Also, if you are running your project under debug (set in the web.config) then you won't get the bunding, minimizing, optimizations, etc, but you would in production. To force these in development, set debugging to false in the web.config.

Here is a list of CdnFallbackExpression values for common CDNs.

## Library ##      ## Expression ##
jQuery             window.jQuery  
jQuery.UI          window.jQuery.ui  
Modernizr          window.Modernizr  
Bootstrap          $.fn.modal  
jquery.transit     $.transit  
jquery.validate    $.validator  
json2              JSON.stringify  
webfont            WebFont  
jquery.blockUI     $.unblockUI()  
respond            window.respond  
moment             window.moment 
dataTables         $.fn.dataTable

NOTE: List copied from here and the augmented.
Great post on CDN

Quick review of nice Open Source JavaScript Grids / Data Tables



DataTables

Website: http://datatables.net/
This is a very powerful and mature Grid and my top choice. My only complaint is that it is almost overwhelming because it is so feature rich and if you need editing, the coolest features you have to pay for. It supports just about any scenario out there and the docmentation is GREAT. It does a good job making simple cases easy to do though. In fact, they have a generator that generates all the code you need to get started after you specify how you want to use it, but that unfortunately is with the paid Editor. They do have for free a tool to help you figure out exactly what files you need for downloading based on your needs. It does allow cells to have input elements (see example), but there isn't any special support for them unless you buy the Editor. If you go that route, it has inline editing, popup screen editing, and single field editing just like the Editablegrid product (below) does AND is supported specifically with ASP.NET (and PHP), but again only for the paid Editor. It does support having all the rows editable at once though. It is very easy to use, but has lots of ways to do very advanced things. It can get data from the server or client. Works well with large amounts of data. The documentation is very well done. There are lots of examples and they include how it was done. It also has extensions for exporting data to Excel, etc.


Bootstrap Table

Website: http://bootstrap-table.wenzhixin.net.cn/
This one is good and has examples in GitHub, but the documentation / demo on the site is quite light. It does have additional documentation and examples on GitHub though. It is nice that users can export data to multiple formats, choose just the columns they want, search, etc. If you click on a cell it will bring up an editor for that field and can have associated validation with it.


Editablegrid

Website: http://www.editablegrid.net
This one is uniquely designed for inline editing. To edit a cell, just click it and it becomes editable. It supports PHP binding, but doesn't seem to support ASP.NET directly, but may not matter unless you need mass amounts of data editing. This grid is a bit light on the features, but is still pretty nice.

How to change the default Name of a TextBox when using MVC, Razor

We want this format so that each Name on the form is unique. Sometimes we need to change what the value of Name is on the HTML form.

Here is the simple example using @Html.TextBoxFor() to change it from the default of "StartTime" to "MyStartTime":

@Html.TextBoxFor(modelItem => item.StartTime, new { Name = "MyStartTime"})

Below is an example of how to set the Name of the StartTime TextBox when looping through a collection of complex objects such as an Appointment
In the html, the INPUT will have a names like:
Appointments[0].StartTime
Appointments[1].StartTime

The example below formats the Name html property to the format that the MVC binder understands and will automatically create the Appointment objects and bind to them.To better understand how the binding in MVC works, check out this article.

This is possible because @Html.EditorFor takes a parameter for the Name, but @Html.HiddenFor.

If you want to use @Html.TextBoxFor instead, it doesn't have this option, but we can use the htmlAttributes parameter. In this case, Name is CASE SENSITIVE. Using name will not work right.

 @{
        var @i = 0;
    }
    @foreach (var item in Model)
    {
                @Html.EditorFor(modelItem => item.StartTime, "TextBox", "Appointments[" + @i + "].StartTime", null)
                @Html.TextBoxFor(modelItem => item.StartTime, new { Name = "Appointments[" + @i + "].StartTime"})

                 i++;
    }


NOTE: You can also use a for loop instead of the foreach.
NOTE: This technique should also work for the other Html helpers, but I have not tested it.

Monday, November 23, 2015

Get a list of ApplicationUsers (Users) in MVC 6

If you need a list of all the user in your MVC 6 application.

The following will work from any controller.

using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.Owin;
...
 var users = Request.GetOwinContext().GetUserManager().Users;

The generated controllers have a line like this:

private ApplicationDbContext db = new ApplicationDbContext();

After the above initialization takes place, you can also get a list of users by simply doing:

db.Users

Notice, I am NOT using db.ApplicationUsers which you may have been tempted to add to the ApplicationDbContext class using the following:

public DbSet ApplicationUsers { get; set; }

The problem as noted here is that that IdentityDbContext already has the following defined.

public virtual IDbSet Users { get; set; }

So, by adding the ApplicationUsers line above you have added two properties that map to the ApplicationUsers. Here is the error you will get if you have done this:

Multiple object sets per type are not supported. The object sets 'ApplicationUsers' and 'Users' can both contain instances of type 'MyApp.Models.ApplicationUser'.


Tuesday, November 10, 2015

Command Line to set permissions recursively

Open a command prompt and  run as Administrator. Next execute a command like the following

icacls "D:" /T /grant Everyone:(OI)(CI)F

If you do icacls as the command prompt you will get help on the command.

You can replace Everyone with an approprate user. You can also specify less than full control.