Wednesday, October 15, 2014

Customize ASP.NET Identity

In ASP.NET used several methodologies for authentication and authorization for the user. First used ASP.NET membership system then ASP.NET simple membership system. After that used ASP.NET Universal Providers. After all of these methodologies now Microsoft recommend to use ASP.NET Identity which is introduce with eliminating most of faults and loopholes contain with previous methods. You can read about more information from here.

In this post I'm going to shows the way of customize the ASP.NET identity match with our own business scenario.When you create the MVC application using default template in Visual Studio, it creates the schema using code-first method for authentication and authorization. In this post I'm going to show how customize the role entity, user entity and use our own database for the schema. First create the empty MVC project like in below.


Then install following packages from NuGet as shown in below. 


First of all create the custom user class and custom role class. Custom user class inherit from IdentityUser and Custom role class inherit from IdentityRole. Following shows CustomIdentityUser class. FirstName and LastName added to the custom user class. Like this we can add any custom field we need according to the business scenario.
public class CustomIdentityUser : IdentityUser
 {
  public string FirstName { get; set; }
  public string LastName { get; set; }
 }

Following shows CustomIdentityRole class. In here Description added to the custom role class.

public class CustomIdentityRole : IdentityRole
 {
  public string Description { get; set; }

  public CustomIdentityRole()
  { 
  }

  public CustomIdentityRole(string roleName, string description) : base(roleName)
  {
   this.Description = description;
  }
 }

After that create custom DB context as shown in below.
 public class CustomIdentityDbContext : IdentityDbContext
 {
  public CustomIdentityDbContext() : base("connectionString")
  {

  }
 }

Then create new database and create the connection string in web.config file as shown in below. In this example my custom DB name is CustomIdentityDb.
 
  
 

After these steps create OWIN startup class like shown in below. Go to add new items under project and add startup class. This class configure authentication scheme and uses cookie based authentication method in here. Path string point to the security controller action.
public class OwinStartup
 {
  public void Configuration(IAppBuilder app)
  {
   CookieAuthenticationOptions options = new CookieAuthenticationOptions();
   options.AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie;
   options.LoginPath = new PathString("/security/Register");
   app.UseCookieAuthentication(options);
  }
 }

After create OWIN start up class should creates model classes needs for view pages. Model class creates under model folder in project template which are Login and Register.
public class Login
 {
  [Required]
  [Display(Name = "User name")]
  public string UserName { get; set; }

  [Required]
  [DataType(DataType.Password)]
  [Display(Name = "Password")]
  public string Password { get; set; }

  [Display(Name = "Remember me?")]
  public bool RememberMe { get; set; }
 }

public class Register
 {
  [Required]
  public string UserName { get; set; }

  [Required]
  public string Password { get; set; }

  [Required]
  [Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
  public string ConfirmPassword { get; set; }

  [Required]
  [EmailAddress]
  public string Email { get; set; }

  public string FirstName { get; set; }

  public string LastName { get; set; }
 }

In these models uses basic validation against model properties. Next step is creation of Security controller. Following code snippets shows security controller which contains the login, logout and register actions. Login and register action contains with GET and POST actions. In this application create another controller called ''Home" and redirect success logins to that controller.
 public class SecurityController : Controller
 {

  private UserManager userManager;
  private RoleManager roleManager;

  public SecurityController()
  {
   CustomIdentityDbContext db = new CustomIdentityDbContext();

   UserStore userStore = new UserStore(db);
   userManager = new UserManager(userStore);

   RoleStore roleStore = new RoleStore(db);
   roleManager = new RoleManager(roleStore);
  }

  // GET: Security
  public ActionResult Index()
  {
      return View();
  }

  public ActionResult Register()
  {
   return View();
  }

  [HttpPost]
  [ValidateAntiForgeryToken]
  public ActionResult Register(Register model)
  {
   if (ModelState.IsValid)
   {
    CustomIdentityUser user = new CustomIdentityUser();

    user.UserName = model.UserName;
    user.Email = model.Email;
    user.FirstName = model.FirstName;
    user.LastName = model.LastName;

    IdentityResult result = userManager.Create(user, model.Password);

    if (result.Succeeded)
    {
     userManager.AddToRole(user.Id, "Administrator");
     return RedirectToAction("Login", "Security");
    }
    else
    {
     ModelState.AddModelError("UserName", "Error while creating the user!");
    }
   }
   return View(model);
  }

  public ActionResult Login(string returnUrl)
  {
   ViewBag.ReturnUrl = returnUrl;
   return View();
  }

  [HttpPost]
  [ValidateAntiForgeryToken]
  public ActionResult Login(Login model, string returnUrl)
  {
   if (ModelState.IsValid)
   {

    CustomIdentityUser user = userManager.Find(model.UserName, model.Password);
    
    if (user != null)
    {
     IAuthenticationManager authenticationManager = HttpContext.GetOwinContext().Authentication;
     authenticationManager.SignOut(DefaultAuthenticationTypes.ExternalCookie);
     ClaimsIdentity identity = userManager.CreateIdentity(user, DefaultAuthenticationTypes.ApplicationCookie);
     AuthenticationProperties props = new AuthenticationProperties();
     props.IsPersistent = model.RememberMe;
     authenticationManager.SignIn(props, identity);
     if (Url.IsLocalUrl(returnUrl))
     {
      return Redirect(returnUrl);
     }
     else
     {
      return RedirectToAction("Index", "Home");
     }
    }
    else
    {
     ModelState.AddModelError("", "Invalid username or password.");
    }
   }

   return View(model);
  }

  [HttpPost]
  [Authorize]
  [ValidateAntiForgeryToken]
  public ActionResult LogOut()
  {
   IAuthenticationManager authenticationManager = HttpContext.GetOwinContext().Authentication;
   authenticationManager.SignOut();
   return RedirectToAction("Login", "Security");
  }

  }
}
Now creates views for the login and register actions using scaffolding. After these steps create helper class for the role creation and call it from application start.
public static void CreateRoles()
  {
   CustomIdentityDbContext db = new CustomIdentityDbContext();

   RoleStore roleStore = new RoleStore(db);
   RoleManager roleManager = new RoleManager(roleStore);

   if (!roleManager.RoleExists("Administrator"))
   {
    CustomIdentityRole newRole = new CustomIdentityRole("Administrator", "Administrators can add, edit and delete data.");
    roleManager.Create(newRole);
   }

   if (!roleManager.RoleExists("Operator"))
   {
    CustomIdentityRole newRole = new CustomIdentityRole("Operator", "Operators can only add or edit data.");
    roleManager.Create(newRole);
   }
  }

Let's test the application now. After you first run the application all tables needs for operate ASP.NET identity creates in DB. Following shows images of testing of this application.

Database table

Registration view with custom fields

Login view

Wednesday, September 3, 2014

Mobile Apps: Develop once and Run in all platforms

All most every mobile developer would like to reach large audience with all platforms. But the blocker for that approach is each time they want to develop the app again. So it take effort and time. In this kind of a scenario c# developers can use Xamarin and Apache Cordova. In earlier post  I described how to use Nomad visual studio extension to develop mobile app for the apache cordova. In this post going to describe about Microsoft developed visual studio extension for cross-platform mobile applications using HTML, CSS, and JavaScript.

First of all Download and install the extension on Visual Studio 2013 Pro Update 3. This extention gives all the set of tools need for development.


After you set-up the development environment, can create new project as shown in below.


After you create a new project, can change the target development platform going properties of the project. Under properties go to configuration manager window and change it as shown in following image. And also you need to change the Platform under project properties as well.


This VS extension also contain one main page as same like Nomad VS extension which is index html page. And also this project template create with configuration file. You can configure application level settings, specify HTTP uri that can access by application and Apache Cordova capabilities.
And this extension include Apache Cordova intellisense support for common Cordova plugins using both JavaScript and TypeScript.

And one of other main feature I saw in this extension compare with Nomad extension is debugging capability. In Nomad extension you don't get this capability unless you use browser developer tools. At that it was headache for me because of compare with time.

With Nomad VS extension we got only ripple emulator for application simulation purposes. But with this extension you get three options to test your app. First one is you can use ripple as usual. Second native emulators and third option is device. With my experience of developing cross platform mobile application I always choose the device for app simulation purposes. Because most of the time whatever we see in the simulator getting change when we deploy it into device.

So these are the basic details of this new Multi-Device Hybrid app development VS extension. I think this post will help you get start on with this new tool. 

Wednesday, August 13, 2014

SPA with AngularJs

 

AngularJS is a JavaScript frame work which use to create dynamic web applications. Its runs with plain JavaScript and HTML, so you don’t need use any other things when you are creating a web applications. You can read and learn more about the AngularJs from this link. In this post going to explain about the steps needs to follow when creating a SPA (Single Page Application) with AngualrJS.

Open your visual studio and create an empty web application. Install AngularJS core and router files using NuGet. After that create a folder called “app”. In this folder going to hold the old AngularJS related scripts files. Inside of this folder create a file calle “app.js”. In this JavaScript file is going to initialize all configurations when angular start up. Folder structure would be like as shown in below.

app

---------controller

--------------main.js

--------------submain.js

---------app.js

views

---------main

------------main.html

index.html

inside app folder contain the controller folder. It hold two angular controllers such as main and submain. And there is views folder for keep all the views. There is another subfolder call “main” to hold the views belongs to main controller. Index view is the initial view start in the application. In app.js file place the following code snippets.

var app = angular.module('spaapp', ['spaapp.controllers', 'ngRoute']);

var appctrl = angular.module('spaapp.controllers', []);

app.config(['$routeProvider', '$locationProvider', function ($routeProvider, $locationProvider) {
    $routeProvider
      .when("/",
      {
          templateUrl: "views/main/main.html",
          controller: "main"
      })
      .when("/sub",
      {
          templateUrl: "views/main/submain.html",
          controller: "submain"
      })
      .otherwise({
          redirectTo: '/'
      });

    $locationProvider.html5Mode(true);
}]);
In here main module create as “spaapp”. Its getting inject with “ngRoute” and “spaapp.controllers”. The “ngRoute” use for client side routing inside the application and “spaapp.controllers” use as module of the controllers in the application. after that shows routing configuration of the application. When user navigate to root url, route configuration load the main controller with main.html view. As the same way it does for the “/sub” path.
So lets create content of the index.html view. 
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
    <base href="/" />
</head>
<body ng-app="spaapp">

  <ng-view></ng-view>

    <script src="Scripts/angular.min.js"></script>
    <script src="Scripts/angular-route.min.js"></script>
    <script src="app/app.js"></script>
    <script src="app/controller/main.js"></script>
    <script src="app/controller/submain.js"></script>
</body>
</html>
Now what we left to do is creation of the main and submain controllers.
main controller
appctrl.controller('main', ['$scope', function ($scope) {
    $scope.message = 'main';
}]);
In main controller use the controller module created earlier in app.js file. This controller inject with $scope for handle the model. In this controller bind message to the $scope property called “message”. Following shows the main.html view for the above controller. This view contain route for the sub controller.
main.html view
<p>The controller name is {{message}}!</p>

<a href="/sub"> Sub Controller </a>
submain controller 
appctrl.controller('submain', ['$scope', function ($scope) {
    $scope.message = 'sub main';
}]);

The submain controller is doing same thing as the main controller. In below showing a submain.html view. This view also same likes the main.html view. It has a link to navigate to the main view.

sub main view
<p>The controller name is {{message}}!</p>

<a href="/"> Back to Main Controller </a>

In this SPA, we load to views dynamically to the index.html. This magic happens through “<ng-view>” tag in the index.html. main and submain views get append to the “<ng-view>” tag when it called through the router. Route configuration handle the controller and view according to the route. Now run the application.
Main View
1_thumb[3]

Sub Main View, you can see url of the browser.

2_thumb[1]

So we created SPA using an AngularJs. Give a try on this.

Happy Coding wlEmoticon-smile[2]

Sunday, August 3, 2014

Windows 8.1 : Flyouts

In windows 8 apps development if wants to integrate flyout for app you don't have any straight forward way to do it. For this kind of a things I used popup control as flyout or third party library like callisto. But in windows 8.1 app development you don't need to be struggle like that way. Because now its integrate with base control library. 

Let's get a scenario like needs to get information from the button click. Now you can do this very simply way setting up the flyout property in the button. 

<Button x:Name="AddButton" Content="Add" Foreground="Black" Height="66" Margin="-3" Width="157" BorderBrush="Black" VerticalAlignment="Top" HorizontalAlignment="Right" FontSize="26.667"> <Button.Flyout> <Flyout Placement="Bottom"> <StackPanel Height="439" Width="294" HorizontalAlignment="Right" Margin="0,5,0,0"> <TextBlock Style="{StaticResource BaseTextBlockStyle}" Text="Add Task" Height="29" FontWeight="Bold" SelectionHighlightColor="{x:Null}" FontSize="21.333" Margin="10,0,10,20"/> <TextBlock HorizontalAlignment="Left" Height="24" Margin="10,0,0,10" TextWrapping="Wrap" Width="145" Text="Projects" FontSize="18.667"/> <ComboBox Height="35" Margin="10,0,10,10"/> <TextBlock HorizontalAlignment="Left" Height="20" Margin="10,0,0,10" TextWrapping="Wrap" Text="Task" Width="199" FontSize="18.667"/> <ComboBox Height="35" Margin="10,0,10,10"/> <TextBlock HorizontalAlignment="Left" Height="30" Margin="111,0,0,10" TextWrapping="Wrap" Text="Hours" Width="77" FontSize="18.667"/> <Slider Height="42" Margin="10,0"/> <TextBox Height="30" Margin="111,0,106,20" TextWrapping="Wrap" Text="1" TextAlignment="Center" BorderThickness="2"/> <CheckBox Content="Billable" Height="37" Margin="7,0,54,10" VerticalAlignment="Stretch" FontSize="18.667"/> <Button Margin="0,5,0,0" Content="Done" Width="120"/> </StackPanel> </Flyout> </Button.Flyout> </Button>

When you click on the add button flyout will shows up like below.


The place where flyout shows up can change using the placment property in the flyout. In above example I used placement position as bottom. You can select top, right, left, full or bottom as placement options. But this depends on the space available on the screen. 

This flyout can have one content item, because of that reason complex UI component must wrapped with StackPanel or Grid item. In this example I used StackPanel. Adding the click event to the button inside the flyout you can perform the action and hide the flyout programmatically.

Sunday, July 20, 2014

Use of ICommand in Windows 8.1 app

Recently I was creating a windows 8.1 app following a MVVM pattern. I was using RelayCommand class in WPF application to create commands that XAML can bind. But unable to build the project because CommandManger class not reference to the WinRT.  The RelayCommand class used for command bind shows in below.

using System; using System.Diagnostics; using System.Windows.Input; namespace WindowsAppMvvm { public class RelayCommand : ICommand { #region Members private readonly Action execute; private readonly Func&lt;bool&gt; canExecute; #endregion #region Constructor public RelayCommand(Action execute) : this(execute, null) { } public RelayCommand(Action execute, Func&lt;Boolean&gt; canExecute) { if (execute == null) throw new ArgumentNullException("execute"); _execute = execute; _canExecute = canExecute; } #endregion #region ICommand Members public event EventHandler CanExecuteChanged { add { if (_canExecute != null) CommandManager.RequerySuggested += value; } remove { if (_canExecute != null) CommandManager.RequerySuggested -= value; } } public Boolean CanExecute(Object parameter) { return _canExecute == null ? true : _canExecute(); } public void Execute(Object parameter) { _execute(); } #endregion } }
Error shown in visual studio.


To solve this issue need to define RelayCommand class without CommandManager. Inside ICommand Members region do following changes.

 1. Remove current CanExecuteChanged event handler and replace with following line
 
public event EventHandler CanExecuteChanged;
 2. Add following method.

public void RaiseCanExecuteChanged() { if (CanExecuteChanged != null) CanExecuteChanged(this, new EventArgs()); }
 Now problem solved and project build successfully.

Tuesday, June 10, 2014

File upload REST service

I needed to create REST service which have capability to upload the file sent from the any client application consume this service.  To achieve this used Web API to create REST service. Following code snippets shows the REST service method written in FileUpload controller.

  /// 
  /// Uploads the file.
  /// 
  /// 
  /// Status of the file upload.
  /// 
  /// 
  public async Task UploadFile()
  {
   if (!Request.Content.IsMimeMultipartContent())
   {
    throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
   }

   string root = HttpContext.Current.Server.MapPath("~/App_Data");
   MultipartFormDataStreamProvider provider = new MultipartFormDataStreamProvider(root);

   try
   {
    await Request.Content.ReadAsMultipartAsync(provider);
    return Request.CreateResponse(HttpStatusCode.OK);
   }
   catch (System.Exception e)
   {
    return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, e);
   }
  }

In this scenario client application would be MVC web application. Following shows code snippets for the view.
@{
    ViewBag.Title = "File Upload";
}

File Upload

@ViewBag.Message @using (Html.BeginForm("Index", "Home", FormMethod.Post, new { enctype = "multipart/form-data" })) { }

After needs to create controller action which can get the file from view and upload it via REST service. Action method code snippets shown in below. This controller contain with GET and POST action methods.
  /// 
  /// Indexes this instance.
  /// 
  /// 
  /// Result for the user given request.
  /// 
  [HttpGet]
  public ActionResult Index()
  {
   return View();
  }

  /// 
  /// Indexes the specified file.
  /// 
  /// 
  /// The uploaded file.
  /// 
  /// 
  /// Response for the status of the file upload.
  /// 
  [HttpPost]
  public async Task Index(HttpPostedFileBase file)
  {
   string uploadUrl = "http://localhost/FileUpload/api/FileUpload/UploadFile";

   if (file != null && file.ContentLength > 0)
   {
    try
    {
     using (HttpClient client = new HttpClient())
     {
      using (MultipartFormDataContent content = new MultipartFormDataContent())
      {
       BinaryReader br = new BinaryReader(file.InputStream);
       byte[] buffer = br.ReadBytes(file.ContentLength);
       br.Close();

       content.Add(new StreamContent(new MemoryStream(buffer)), "UploadedFiles", file.FileName);
       HttpResponseMessage httpResponse = await client.PostAsync(uploadUrl, content);

       if (httpResponse.IsSuccessStatusCode)
       {
        ViewBag.Message = "File uploaded successfully";
       }
      }
     }
    }
    catch (Exception ex)
    {
     ViewBag.Message = string.Format("ERROR: {0}", ex.Message);
    }
   }
   else
   {
    ViewBag.Message = "You have not specified a file.";
   }

   return View();
  }

Now run and test the application.


Tuesday, May 13, 2014

Sequence of SQL Query Statement

As a developer all of us write SQL queries for access and manipulate data in  the database. When retrieve data from database SQL query start with SELECT statement. In these SQL queries are create English-like manner. But its logical execution not process like that way. The SELECT statement logically execute in following order.

  1. FROM
  2. WHERE
  3. GROUP BY
  4. HAVING 
  5. SELECT
  6. ORDER BY 
Following SQL query retrieve employee detail from EmployeeLeave table. 


SELECT EmpId, FirstName, COUNT(*) AS NumLeaves
FROM EmployeeLeave
WHERE EmpId = 12
GROUP BY DepId, LeaveYear
HAVING COUNT(*) > 1
ORDER BY EmpId, DepId

But this query logically process in following manner. 

FROM EmployeeLeave
WHERE EmpId = 12
GROUP BY DepId, LeaveYear
HAVING COUNT(*) > 1
SELECT EmpId, FirstName, COUNT(*) AS NumLeaves
ORDER BY EmpId, DepId

Following shows the way of this query works,
  1. Queries the rows from EmployeeLeave table
  2. Filters only records where employee ID equal to 12
  3. Groups the records by department ID and leave year
  4. Filters only groups having more than one leave
  5. Selects for each group the employee ID, first name and number of leaves
  6. Order the rows in the output by employee ID and department ID
The knowing the way of logical execution of SQL query is very important when write the queries for our business scenarios. It give us more understand about how our query works and its a big help to structure the query as well.