Sunday, May 1, 2016

Some thoughts on putting JavaScript, CSS, Images inside wwwroot folder

Last week, our team spent time in converting JavaScript to TypeScript and CSS to LESS and re-structuring our client side developer workflow.  In this post, I just want to focus on the wwwroot folder.  We do our web development using ASP.NET MVC and there is still lot of code in Web Forms too. We wanted to bring sanity to our growing CSS and JavaScript code as we are doing more and more client side code.  So we took some cues from ASP.NET core on how it is organizing code. And we followed basically the same approach.  Put everything inside wwwroot folder like below.

>wwwroot
>>>css
>>>js
>>>lib

We had discussion amongst us and here are our reasons for sticking with it. I know ASP.NET Core team must have had their reasons for doing it and our reasons may well be what they must have been thinking.

1. Everything client side is inside one folder.

Imaging currently if you are working inside ASP.NET MVC web app then you have something CSS inside Content folder, then JavaScript inside Scripts folder, then images in images folder. And these folders are separated apart. If you have lot of resources you may be spending time scrolling looking for a particular file. [Tip: If you use VSCode then Ctrl+P you can help you open a file very quickly]

2. wwwroot starts with w.

Alphabetically wwwroot it is at the end in folder list and you don’t have to go looking for stuff.  You know it is at the bottom and everything is in there. We thought of names like web, public but we stuck with wwwroot folder for now.

If you find any great discussion on this topic please share with me in the comments below.

Saturday, April 30, 2016

Use Get-CommandVariable to auto generate variables for a command

In this post, I want to share a silly new PowerShell command Get-CommandVariable that I wrote and it is available on github as a powershell module and you can put inside your modules folder and start using it.  “What problem this is trying to solve?” you might be thinking.

You start writing a powershell script and you want to pass variables to a command.  For example, you want to create a new AzureRM Web app using command New-AzureRMWebApp. Then you will have to write your command like this using $variables.

$ResourceGroupName = "mycustomresourcegroup"
$Name = "webapp01"
$Location = "centralus"

New-AzureRMWebApp  -ResourceGroupName $ResourceGroupName -Name $Name -Location $Location

Let’s understand what you had to go through. Type all the parameters and its variables with a $sign.  Copy those variables at the top so you can initialize them. That’s not the tricky part. The thing that gets me the most is trying to think names for those variables and then copy the variables at the top.

So Get-CommandVariable will create this all for you.  How?  Just specify for which command you want to generate automatic $variables and it will do it. In the below example, we are using New-AzureRMWebApp command and after it generates the output,  I just copy the text and put it inside ISE window.

PS C:>Get-CommandVariable –CommandName New-AzureRMWebApp
$ResourceGroupName = ""
$Name = ""
$Location = ""
New-AzureRMWebApp -ResourceGroupName $ResourceGroupName -Name $Name -Location $Location

If you are using powershell for quite a long time you may know that powershell commands have certain parameters as mandatory and others are not mandatory.  Then there are commands that will work different combination of parameters. And Get-CommandVariable will work in those scenarios as well.

For example, if you provide –ShowAll option it will generate variables for all the parameters not just mandatory ones.

PS C:>Get-CommandVariable –CommandName New-AzureStorageAccount -ListParameterSets
$StorageAccountName = ""
$Label = ""
$Description = ""
$AffinityGroup = ""
$Type = ""
$Profile = ""

New-AzureStorageAccount  -StorageAccountName $StorageAccountName -Label $Label -Description $Description -AffinityGroup $AffinityGroup -Type $Type -Profile $Profile

You can specify to list all the ParameterSets (think: different combinations of parameters) that a particular command expects. For example,

PS C:>Get-CommandVariable –CommandName New-AzureStorageAccount -ListParameterSets
Name
----
ParameterSetAffinityGroup
ParameterSetLocation

Then you can tell Get-CommandVariable to generate variables for a particular ParameterSet. In the below example we are chosing ParameterSetAffinityGroup
PS C:>Get-CommandVariable –CommandName New-AzureStorageAccount  -ParameterSetName ParameterSetAffinityGroup
$StorageAccountName = ""
$AffinityGroup = ""

New-AzureStorageAccount  -StorageAccountName $StorageAccountName -AffinityGroup $AffinityGroup
By default, I am showing just the mandatory parameters, since my goal to get going as quickly as possible. To show all parameters you will have to provide –ShowAll flag. So that’s it and if you think this might be useful to you then give it a try. You can provide feedback in the comments below or submit issues directly on github as well.

Sunday, April 3, 2016

PowerShell Tip: Start-Transcript and Stop-Transcript

You are trying to write a powershell script but you don’t know all the right comands to execute and what parameters to pass.  So you write a bunch of commands, out of which many don’t work and some work. After lots of experimentation you finally find the right commands with right parameters that would work for your script. You can do Get-history to get a list of all the commands that were executed. But that history only gets persisted as long as you have the powershell window open. Once you close the window that history is gone. I have closed the console window many times and found myself cursing for having done so because I couldn’t remember those commands. Now I have to again fiddle with those commands. Wouldn’t it be nice if there was something that would record everything you did in a text file? Once you are done experimenting you could tell it to stop recording your session and then you can use that text file for later reference. 
Start-Transcript and Stop-Transcript does just that. Before you start experimenting just tell PowerShell you want to record stuff in a text file and Start-Transcript will do that.  After you are done you can use Stop-Transcript to stop recording.  I like this feature. But there is more.
See in the Start-Transcript you have to provide a txt file and I don’t like providing path information with a uniquename everytime I want to do Start-Transcript and I want it to be automatic.  Below function will create a uniquename of the file based upon a timestamp. Now if you wish to provide a meaningful name then you can do that too. The script will append a unique timestamp to that name.  You can put this function into your profile and it will be available to you when the console loads.
function start-recording {
param(
 [string]$sessName
)
try { stop-transcript } catch {}
$uniqFileName = (get-Date).ToString('MMddyyyyhhmmss');
if([System.String]::IsNullOrEmpty($sessName)){
 Start-Transcript -Path "C:\Scripts\Transcripts\$uniqFileName.txt" -NoClobber 
}
else{
Start-Transcript -Path "C:\Scripts\Transcripts\$sessName$uniqFileName.txt" -NoClobber  
}
}

set-alias stop-recording stop-transcript 
I invoke command -  Start-Recording “webpackge” and a unique file name is created in my scripts/transcripts folder by that name.  The function also does stop-transcript if you execute the function start-recording again so it does saves existing session and starts recording another one. 

Sunday, November 29, 2015

Making the Setup phase of Unit testing easier with StructureMap and FakeItEasy

In this post I am going to show you how I am using StructureMap Registry along with FakeItEasy to make the setup phase of my unit tests easier.  By no means I am claim that this is how it should be done but I feel it can be done this way. If you find any issues or it could be done better please let me know in the comments below. I will be happy to correct it and respond. In this post I am assuming you know about StructureMap, Dependency Injection, FakeItEasy and Unit Testing in general.

First about the problem I was facing and I am sure you must have faced it too and already solved it some other way. My system under test in this example is about an OrderingService which is responsible for placing orders, checking if inventory is there in warehouse or not and notify via email and log messages to database. Below is the code for OrderingService.  We are not interested in the details for the PlaceOrder function here.

 public interface IOrderingService
{
bool PlaceOrder(Order order);
}
public class OrderingService : IOrderingService
{
private IPaymentService _paymentService;
private IWarehouseService _warehouseService;
private ILoggingService _loggingService;
private IEmailService _emailService;
public OrderingService(
IPaymentService paymentService,
IWarehouseService warehouseService,
ILoggingService loggingService,
IEmailService emailService)
{
_paymentService = paymentService;
_warehouseService = warehouseService;
_loggingService = loggingService;
_emailService = emailService;
}
public bool PlaceOrder(Order order)
{
throw new NotImplementedException();
}
}

Like any system one system depends on the other and we now have a graph of dependency. For example, LoggingService depends upon IDataManager and EmailService depends upon ISmtpService.

  public interface ILoggingService
{
void Log(string logText);
}
public class LoggingService : ILoggingService
{
private IDataManager _dataManager;
public LoggingService(IDataManager dataManager)
{
_dataManager = dataManager;
}
public void Log(string logText)
{
throw new NotImplementedException();
}
}

I am not showing code for EmailService for brevity. With such graph my setup phase of the unit tests started to look like following.

  [TestClass]
public class BadOrderingServiceTests
{
//All Fakes to be injected.
private IPaymentService _paymentService;
private IEmailService _emailService;
private ILoggingService _loggingService;
private IWarehouseService _warehouseService;

//SUT
private IOrderingService _orderingService;

[TestInitialize]
public void Setup()
{
var smtpService = A.Fake<SmtpService>(
x => x.WithArgumentsForConstructor(
() => new SmtpService("Fake Smtp Server")));

_emailService = A.Fake<EmailService>(
x => x.WithArgumentsForConstructor(
() => new EmailService(smtpService)));


var dataManager = A.Fake<DataManager>(
x => x.WithArgumentsForConstructor(
() => new DataManager("Connection String")));

_loggingService = A.Fake<LoggingService>(
x => x.WithArgumentsForConstructor(
() => new LoggingService(dataManager)));

_paymentService = A.Fake<IPaymentService>();
_warehouseService = A.Fake<IWarehouseService>();

//SUT
_orderingService = new OrderingService(_paymentService,_warehouseService,_loggingService,_emailService);
}

[TestMethod]
public void PlaceOrder_OnPassingNonNullOrder_ShouldPlaceOrderSuccessfully()
{
//Arrange
var fixture = new Fixture();
var order = fixture.Create<Order>();

//Act
var result = _orderingService.PlaceOrder(order);

//Assert
Assert.IsTrue(result);
}
}

So you see in the setup method how much ceremony it requires to test this ordering service and if you have to do this again for another service then again all the dependencies have to be hooked in like this. Now for simplicity the paymentService and warehouseservice doesn’t take in any dependency so it is just a straight A.Fake<IPaymentService>().  This is all handy dandy for testing one service. But this isn’t ideal if you want to test another service which may require similar setup.  And another thing I kept reading everywhere is writing unit tests should be fast and easy and the setup should feel just like how you wrote your system under test. Clearly the setup phase is way different from how we wrote the OrderingService above.  You may ask how it is different? In the constructor of OrderingService, do you have to worry where LoggingService is getting its IDataManager from or EmailService getting its ISmtpServer? No right. Because it is being taken care by StructureMap registry like below.

    public class StructureMapRegistry : Registry
{
public StructureMapRegistry()
{
Scan(scan =>
{
scan.TheCallingAssembly();
scan.WithDefaultConventions();
scan.SingleImplementationsOfInterface();
});

For<IDataManager>().Singleton().Use<DataManager>()
.Ctor<string>("connectionString")
.Is("Production Connection String");

For<ISmtpService>().Singleton().Use<SmtpService>()
.Ctor<string>("smtpServer")
.Is("Production Smtp Server");
}
}

So you may ask why are you writing your setup that way. One reason is that I didn’t knew any other way and I learnt stuff harder way using google.  For now lets focus on a light bulb moment that inspired me to make my code better.  And here is a better way according to me. Just like how StructureMap took care for me the registration of all  dependencies [I love you StructureMap] of OrderingService why not StructureMap take of registering all the Fake dependencies [light blub].  Let’s create a different Registry which we will call FakeStructureMapRegistry.cs

 public class FakeStructureMapRegistry : Registry
{
public FakeStructureMapRegistry()
{
Scan(scan =>
{
scan.TheCallingAssembly();
scan.WithDefaultConventions();
});

For<IDataManager>()
.Singleton()
.Use(A.Fake<DataManager>(
y => y.WithArgumentsForConstructor(() =>
new DataManager("Fake Connection String"))));


For<ISmtpService>()
.Singleton()
.Use(A.Fake<SmtpService>(
y => y.WithArgumentsForConstructor(() =>
new SmtpService("Fake Smtp Server"))));

For<ILoggingService>().Use(A.Fake<ILoggingService>());
For<IPaymentService>().Use(A.Fake<IPaymentService>());
For<IWarehouseService>().Use(A.Fake<IWarehouseService>());
For<IEmailService>().Use(A.Fake<IEmailService>());
For<IOrderingService>().Use(A.Fake<IOrderingService>());
}
}

Question: Why I am also registering SUT OrderingService inside FakeStructureMapRegistry? Because in this Fake registry I don’t want to keep changing which class is under test and which one isn’t. I will register all the Fakes at once and not worry about it. More on that in the next paragraph. Now we will use this Fake registry in our setup method. So here is how my modified unit test looks like.

  [TestClass]
public class OrderingServiceTest
{
private IPaymentService _paymentService;
private IEmailService _emailService;
private ILoggingService _loggingService;
private IWarehouseService _warehouseService;
private IContainer _container;

//SUT
private IOrderingService _orderingService;

[TestInitialize]
public void Setup()
{
_container = new Container(x => x.AddRegistry(new FakeStructureMapRegistry())); //registering all FAKES.
_container.EjectAllInstancesOf<IOrderingService>(); //ejecting FAKE SUT
_container.Configure(x => x.AddType(typeof(IOrderingService), typeof(OrderingService))); //registering SUT

_paymentService = _container.GetInstance<IPaymentService>();
_emailService = _container.GetInstance<IEmailService>();
_loggingService = _container.GetInstance<ILoggingService>();
_warehouseService = _container.GetInstance<IWarehouseService>();
_orderingService = _container.GetInstance<IOrderingService>();
}
[TestMethod]
public void PlaceOrder_OnPassingNonNullOrder_ShouldPlaceOrderSuccessfully()
{
//Arrange
var fixture = new Fixture();
var order = fixture.Create<Order>();

//Act
var result = _orderingService.PlaceOrder(order);

//Assert
Assert.IsTrue(result);
}
}

Let’s go into detail about the first three lines in the Setup method and rest is self explanatory.  Line 1 – we create a new structuremap container and add our FakeStructureMapRegistry class. That takes care of configuring all the Fake dependencies including our SUT which should never be a mocked or faked object. Hence line 2 – which tell the container to eject all the instances of IOrderingService because I will configure it as not Fake and real OrderingService on Line 3. So that’s all. The rest of the lines gets instances from the container which will look  a bit familiar to the constructor of OrderingService.  I love this setup method. This exactly feels how I would write my system under test.  If you were to configure another service say LoggingService then it would be like this.

[TestClass]
public class LoggingServiceTest
{
private IContainer _container;
private IDataManager _dataManager;

private ILoggingService _loggingService;
[TestInitialize]
public void Setup()
{
_container = new Container(x => x.AddRegistry(new FakeStructureMapRegistry())); //registering all FAKES.
_container.EjectAllInstancesOf<ILoggingService>(); //ejecting FAKE SUT
_container.Configure(x => x.AddType(typeof(ILoggingService), typeof(LoggingService))); //registering SUT

_dataManager = _container.GetInstance<IDataManager>();
_loggingService = _container.GetInstance<ILoggingService>();
}
}

So that’s it. What do you guys think of this way of setting up? Please let me know in the comments sections below and thank you for reading the post.

Sunday, September 27, 2015

PowerForms update – 0.3.5.3906

If you are new to PowerForms then please checkout previous posts about PowerForms here and here.  This post explains about a new update to PowerForms 0.3.5.3906 which you can download through nuget.  So let’s dive into few new features added to PowerForms.

1. Adding ListBoxFor support to PowerForms and it is similar to how you would use ComboBoxFor

            var form = new PowerForm();
var dt = form.ListBoxFor("Fruits", new string[] { "Apple", "Orange" }).Display();

System.Console.WriteLine(dt["Fruits"].ToString());

System.Console.Read();

2. Adding SelectedIndexChanged event support for ComboBox and ListBoxFor

            var form = new PowerForm();
var dt = form.ListBoxFor("Fruits", new string[] { "Apple", "Orange" }, (o,e) =>
{
System.Console.WriteLine("Inside SelectedIndexChanged Event");
}).Display();

System.Console.WriteLine(dt["Fruits"].ToString());

System.Console.Read();

3.  Adding ButtonFor support. Earlier if you wanted to submit information second time you would have to close the form and run the program again. With ButtonFor you can now add your own Button for which you can specify a custom click action. On the click event you can do other things with the form, for example new GetFormOutput method on the form which gives you the same dictionary<string, object> for submitted form values. You can also close the PowerForm using form.Close() method added to form inside the click event.

	  var form = new PowerForm();

var dt = form.TextBoxFor("FirstName")
.ButtonFor("Click me", (object o, EventArgs e) =>
{
var rs = form.GetFormOutput();
System.Console.WriteLine(rs["FirstName"].ToString());
form.Close();
}).Display();

System.Console.WriteLine(dt["FirstName"].ToString());
System.Console.Read();


4. Adding CheckBoxFor support allows you to add a CheckBox to the form. It gives you out as a boolean if the field is checked or not.

 
var form = new PowerForm();

var dt = form.CheckBoxFor("Yes")
.CheckBoxFor("No")
.Display();
System.Console.WriteLine(dt["Yes"].ToString());
System.Console.WriteLine(dt["No"].ToString());
System.Console.Read();

5. You can now tell the form not to include the default Submit button if you wish to inside the SubmitButton method.

            var form = new PowerForm();

var dt = form.TextBoxFor("FirstName")
.SubmitButton(false).Display();

dt["FirstName"].ToString().ToConsole();
System.Console.Read();

Friday, September 25, 2015

Creating a very simple Ajax Form in ASP.NET MVC 4

In this post, I am going to demonstrate how to create a simple Ajax Form in ASP.NET MVC 4 application using Visual Studio.  I am using Visual Studio 2015 but this should work with VS 2013 too. We are going to submit information about a person using some ajax and with minimum use of javascript.  There is javascript used but we are taking advantage of the wonderful tooling and template benefits of ASP.NET MVC4.  I assume you know some basics of ASP.NET MVC 4 but to get started you create a default asp.net mvc 4 application inside visual studio.

Before diving right into code you may want to check the pre-requisites section below.

PREREQUISITES

Packages.

 You will need if not already installed jQuery, jQuery.UI.Combined, jQuery.Validation, Microsoft.jQuery.Unobtrusive.Ajax, Microsoft.jQuery.Unobtrusive.Validation. Below is how my packages look like.

<?xml version="1.0" encoding="utf-8"?>
<packages>
  <package id="Antlr" version="3.4.1.9004" targetFramework="net451" />
  <package id="bootstrap" version="3.0.0" targetFramework="net451" />
  <package id="EntityFramework" version="6.1.1" targetFramework="net451" />
  <package id="jQuery" version="1.10.2" targetFramework="net451" />
  <package id="jQuery.UI.Combined" version="1.11.2" targetFramework="net451" />
  <package id="jQuery.Validation" version="1.13.0" targetFramework="net451" />
  <package id="Microsoft.AspNet.Identity.Core" version="2.1.0" targetFramework="net451" />
  <package id="Microsoft.AspNet.Identity.EntityFramework" version="2.1.0" targetFramework="net451" />
  <package id="Microsoft.AspNet.Identity.Owin" version="2.1.0" targetFramework="net451" />
  <package id="Microsoft.AspNet.Mvc" version="5.2.2" targetFramework="net451" />
  <package id="Microsoft.AspNet.Razor" version="3.2.2" targetFramework="net451" />
  <package id="Microsoft.AspNet.Web.Optimization" version="1.1.3" targetFramework="net451" />
  <package id="Microsoft.AspNet.WebPages" version="3.2.2" targetFramework="net451" />
  <package id="Microsoft.jQuery.Unobtrusive.Ajax" version="3.2.2" targetFramework="net451" />
  <package id="Microsoft.jQuery.Unobtrusive.Validation" version="3.2.2" targetFramework="net451" />
  <package id="Microsoft.Owin" version="2.1.0" targetFramework="net451" />
  <package id="Microsoft.Owin.Host.SystemWeb" version="2.1.0" targetFramework="net451" />
  <package id="Microsoft.Owin.Security" version="2.1.0" targetFramework="net451" />
  <package id="Microsoft.Owin.Security.Cookies" version="2.1.0" targetFramework="net451" />
  <package id="Microsoft.Owin.Security.Facebook" version="2.1.0" targetFramework="net451" />
  <package id="Microsoft.Owin.Security.Google" version="2.1.0" targetFramework="net451" />
  <package id="Microsoft.Owin.Security.MicrosoftAccount" version="2.1.0" targetFramework="net451" />
  <package id="Microsoft.Owin.Security.OAuth" version="2.1.0" targetFramework="net451" />
  <package id="Microsoft.Owin.Security.Twitter" version="2.1.0" targetFramework="net451" />
  <package id="Microsoft.Web.Infrastructure" version="1.0.0.0" targetFramework="net451" />
  <package id="Modernizr" version="2.6.2" targetFramework="net451" />
  <package id="Newtonsoft.Json" version="6.0.3" targetFramework="net451" />
  <package id="Owin" version="1.0" targetFramework="net451" />
  <package id="Respond" version="1.2.0" targetFramework="net451" />
  <package id="WebGrease" version="1.5.2" targetFramework="net451" />
</packages>

Bundles

 public class BundleConfig
{
// For more information on bundling, visit http://go.microsoft.com/fwlink/?LinkId=301862
public static void RegisterBundles(BundleCollection bundles)
{
bundles.Add(new ScriptBundle("~/bundles/jquery").Include(
"~/Scripts/jquery-{version}.js"));

bundles.Add(new ScriptBundle("~/bundles/jqueryval").Include(
"~/Scripts/jquery.validate*",
"~/Scripts/jquery.unobtrusive-ajax*"));

bundles.Add(new ScriptBundle("~/bundles/jqueryui")
.Include("~/Scripts/jquery-ui-*"));

bundles.Add(new StyleBundle("~/Content/jquerycss")
.Include("~/Content/themes/base/datepicker.css"));

bundles.Add(new ScriptBundle("~/bundles/modernizr").Include(
"~/Scripts/modernizr-*"));

bundles.Add(new ScriptBundle("~/bundles/bootstrap").Include(
"~/Scripts/bootstrap.js",
"~/Scripts/respond.js"));

bundles.Add(new StyleBundle("~/Content/css").Include(
"~/Content/bootstrap.css",
"~/Content/site.css"));

// Set EnableOptimizations to false for debugging. For more information,
// visit http://go.microsoft.com/fwlink/?LinkId=301862
BundleTable.EnableOptimizations = true;
}
}

Let’s dive in.


First we create a person class i.e model in the models folder inside your application. Notice the data annotations used to trigger form validation. These will be triggered on the client side when the user enters invalid information. Most of them are self explanatory however special mention to the confirm password field. It is so easy to do password confirmation here.

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web;

namespace AspNetAjaxForm.Models
{
public class Person
{
[Required()]
[DataType(DataType.Text)]
[StringLength(50, MinimumLength = 3)]
public string FirstName { get; set; }

[Required()]
[DataType(DataType.Text)]
[StringLength(50, MinimumLength = 3)]
public string LastName { get; set; }

[Required]
[DataType(DataType.EmailAddress)]
public string Email { get; set; }

[Required]
public DateTime BirthDate { get; set; }

[DataType(DataType.Text)]
[StringLength(50,MinimumLength=6)]
[Required]
public string Username { get; set; }

[DataType(DataType.Password)]
[StringLength(255, MinimumLength = 8)]
[Required]
public string Password { get; set; }

[Compare("Password")]
[DataType(DataType.Password)]
[StringLength(255, MinimumLength=8)]
public string ConfirmPassword { get; set; }
}
}

Next we will create Register.cshtml page as shown below inside Views/Home folder.  For explanation see paragraph below code

@model AspNetAjaxForm.Models.Person
@{
ViewBag.Title = "Register";
}
<h2>Register</h2>
<div id="register-main">
<div id="register-main-loading-img">
<img id="loading-img" alt="loading" src="~/Content/loadingAnimation.gif">
</div>
@Html.Partial("_RegisterForm",Model)
</div>
@section scripts
{
<script type="text/javascript">
$(document).on('focus', '[data-date="birthdate"]', function () {
$(this).datepicker({
changeMonth: true,
changeYear: true
});
});
</script>
}

In the code above we specify that this form will take in strongly typed model Person. In the register-main div we have two things, one is loading image which is a spinning .gif image that you can easily get from internet and the other is a Partial view called _RegisterForm.cshtml that accepts our Model object. We will create _RegisterForm in the next step.  In the Scripts section we use Jquery to configure our date picker to show month and year field to select Birthdate. Lets’ create _RegisterForm view using the create template with Person as strongly typed object.  Now I have modified the form to use Ajax.BeginForm.  See description of the code below.

@model AspNetAjaxForm.Models.Person

<div id="ajaxForm">
@using (Ajax.BeginForm("Register", "Home", null,
new AjaxOptions
{
HttpMethod = "POST",
InsertionMode = InsertionMode.ReplaceWith,
UpdateTargetId = "ajaxForm",
LoadingElementId = "register-main-loading-img"
}))
{
@Html.AntiForgeryToken()

<div class="form-horizontal">
<h4>Person</h4>
<hr />
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
<div class="form-group">
@Html.LabelFor(model => model.FirstName, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.FirstName, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.FirstName, "", new { @class = "text-danger" })
</div>
</div>

<div class="form-group">
@Html.LabelFor(model => model.LastName, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.LastName, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.LastName, "", new { @class = "text-danger" })
</div>
</div>

<div class="form-group">
@Html.LabelFor(model => model.Email, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Email, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Email, "", new { @class = "text-danger" })
</div>
</div>

<div class="form-group">
@Html.LabelFor(model => model.BirthDate, htmlAttributes: new { @class = "control-label col-md-2"})
<div class="col-md-10">
@Html.EditorFor(model => model.BirthDate, new { htmlAttributes = new { @class = "form-control", data_date = "birthdate" } })
@Html.ValidationMessageFor(model => model.BirthDate, "", new { @class = "text-danger" })
</div>
</div>

<div class="form-group">
@Html.LabelFor(model => model.Username, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Username, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Username, "", new { @class = "text-danger" })
</div>
</div>

<div class="form-group">
@Html.LabelFor(model => model.Password, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Password, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Password, "", new { @class = "text-danger" })
</div>
</div>

<div class="form-group">
@Html.LabelFor(model => model.ConfirmPassword, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.ConfirmPassword, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.ConfirmPassword, "", new { @class = "text-danger" })
</div>
</div>

<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}

<div>
@Html.ActionLink("Back to List", "Index")
</div>
</div>

In the above code, first line is obvious it takes in Person object. We wrap everything into ajaxForm div. The key parts here are as follows:


1. Using Ajax.BeginForm allows us submit form using Ajax.  The parameters say that when I click on the submit button please post this form using “Register” action on the “Home” controller which accepts “POST” request. After the form is submitted replace the contents of “ajaxForm” div with result of request and while you process the request display the loading image we specified earlier. 


2. Everything inside div form-horizontal is created using create a new asp.net mvc 4 view with a strongly typed model of type person. I modified the Birthdate field to take in the jquery ui date picker pay attention to the data_date attribute eg. data_date = "birthdate" we had inside the Register page.


Now we are going to see how everything clubs together. Until now you may be a bit lost. So lets check out our controller.  In the home controller create following methods.

           [HttpGet]
public ActionResult Register()
{
return View(new Person());
}

[HttpPost]
public async Task<PartialViewResult> Register(Person person)
{
await Task.Delay(1000);
if ((new string[] {"mitul1","mitul11","mitul12","mitul13"}).Contains(person.Username))
{
ModelState.AddModelError("Username", String.Format("username {0} is already taken", person.Username));
}
if (ModelState.IsValid)
{
return PartialView("_RegistrationResult");
}
return PartialView("_RegisterForm", person);
}

When you run the application and navigate to /Home/Register page it will hit the first Register method and display the Register.cshtml view. And inside Register.cshtml we have _RegisterFrom.cshtml partial view which will ultimately render the form.  After filling the form out when you click on the submit button the second Register method is called that takes in a Person object. This register method returns a PartialView in both the cases 1. if the form is successful 2. if the form has errors. Lets’ understand the second Register method in a little bit more detail.


1. This method uses async and await since you may be submitting the form to a database or checking validation against a web service asynchronously.  Special notice – See the async keyword on the method signature and because of that we cannot just return PartialViewResult we have decorate the method signature with Task<PartialViewResult>.  For demo purposes, I am using await Task.Delay(1000) instead of an async web call.


2. The first if statement checks if the username is already taken or not. This is just for demo purpose but you may have some complex validation on the server side and if any field is invalid then you want to throw that error back and the user should see it below that field. See the image below. You do that by using the ModelState.AddModelError method which takes in field name and error message. In our case we wanted to display that this username is already taken so we have specified ModelState.AddModelError(“username”,String.Format(”username {0} is already taken”,person.username);  Because of this statement our person model that was submitted by the user is invalidated and we return the same _RegisterForm.cshtml Partial view with person model.


image


3. If the model was valid then we enter into the second if statement and submit our person to a database or call a web service. Based upon you business logic you can do other things like if the form was unsuccessful show different message etc. In our case we are showing a partial view called _RegistrationResult.cshtml. You can modify this view to display either confirmation or error message.


Last but not the least to show stuff properly I am using following CSS.

#register-main{
position:relative;
border:3px solid green;
z-index:10;
}
#register-main-loading-img{
display:none;
position:absolute;
z-index:1;
top:0px;
left:0px;
width:100%;
height:100%;
border:3px solid orange;
background-color:rgba(216, 213, 213, 0.89);
}
#loading-img{
border:3px solid blue;
display:block;
position:relative;
width:100px;
height:100px;
margin-left:auto;
margin-right:auto;
top:50%;
}

 

So that’s about it. If you like this post of have any comments leave in the comments section.

 

 

Friday, September 18, 2015

Visual Studio Extension of the Week: Inline Color Picker

If you are a web developer then most modern IDE’s have this feature and thanks to Web Essentials and ReSharper I am used to seeing color next to their hex code counterpart inside Visual Studio. But if you are working in XAML then by default Visual Studio does not have this feature. In this post I want to mention a visual studio extension Inline Color Picker that displays actual color next to the hex code inside your XAML file. It allows you to pick a color of your choice using a color picker. I wonder why XAML team at Microsoft doesn’t add this feature.

image

image

Note this Extension has been there for Visual Studio 2015, 2013, 2012, 2010 all along.  Go download it if you are working with XAML.