European ASP.NET MVC 4 and MVC 5 Hosting

BLOG about ASP.NET MVC 3, ASP.NET MVC 4, and ASP.NET MVC 5 Hosting and Its Technology - Dedicated to European Windows Hosting Customer

ASP.NET MVC Hosting - HostForLIFE.eu :: Using Ajax in MVC Application

clock June 21, 2016 00:16 by author Anthony

In asp.net web form application, if we need ajax service, we will need to create wcf services on server side to serve ajax calls, while in MVC web application, no wcf is needed, a controller will do.

Here are two examples (GET and POST) of how to use ajax in mvc application

Http Get example: ajax consumer in view

<script type="text/javascript">
  var user = {
                'id': 1
            };
    $.get(
                'home/getUser',
                user,
                function (data) {
                    alert(data.name);
                }
    );
</script>


Http Get example: ajax server in home controller

public class HomeController : Controller
{
    // data GET service
     public JsonResult getUser(int id)
     {
            User user = db.Users.where(u=>u.id==id)
            return Json(user,JsonRequestBehavior.AllowGet);     }
}

A few points:


Controller must return JsonResult rather than ActionResult as a normal controller does as we would want the data to be returnd as json data, and it does not have a ‘d’ wrapper

JsonRequestBehavior.AllowGet must be set in Json()call, otherwise you will get:

500 internal server error with message like

This request has been blocked because sensitive information could be disclosed to third party web sites when this is used in a GET request. To allow GET requests, set JsonRequestBehavior to AllowGet

You only need to set this parameter for GET and returning JSON array to avoid JSON hijacking, no need for POST requests.
Http POST example: ajax consumer in view


<script type="text/javascript">
var user={
            'name':’TheUser’,
            'age':30
        };
 $.post(
            'home/SaveUser',
            user,
            function (data) {
                if (data === true) {
                   alert('User is saved');
                }
                else {

                    alert('Failed to save the user');
                }
            },
            'json'
        );
</script>


Http POST example: ajax server in home controller

public class HomeController : Controller
{
    // data POST service
  [AcceptVerbs(HttpVerbs.Post)]
   public JsonResult SaveUser (string name, int age)
   {
        return Json(true);    }
}

A few points:

Have to decorate the controller with ‘POST’

Datatype in $.post in example is set to json, but it is not necessary to be so, if you just pass data in fields rather than in complex object. When it is not set to json it will use application/x-www-form-urlencoded as a way to pass data in standard post.


Summary:
In asp.net MVC you can use controller as ajax server without having to use wcf, compared with wcf, no configuration is needed

 

HostForLIFE.eu ASP.NET MVC Hosting
HostForLIFE.eu is European Windows Hosting Provider which focuses on Windows Platform only. We deliver on-demand hosting solutions including Shared hosting, Reseller Hosting, Cloud Hosting, Dedicated Servers, and IT as a Service for companies of all sizes. We have customers from around the globe, spread across every continent. We serve the hosting needs of the business and professional, government and nonprofit, entertainment and personal use market segments.



ASP.NET MVC Hosting - HostForLIFE.eu :: Configuring ELMAH In ASP.NET MVC

clock June 13, 2016 21:35 by author Anthony

In this article, I will integrate and setup ELMAH to asp.net MVC project. I will finish whole article in 5 different steps. ELMAH stands for Error Logging Modules and Handlers providing application wide error logging facilities. ELMAH is pluggable and easy to implement without changing single line of code. ELMAH work as interceptor of unhandled dotnet exceptions, that display over yellow screen of death. As per Author you can dynamically add ELMAH on running asp.net application without recompile or re-deploy whole application.You can download ELMAH binaries from google code or if you are using nuget then visit ELMAH nuget page.

Install

The best way to install any module to Asp.net MVC project is to use Nuget package Console. You can visit ELMAH nuget page for get latest version command.

Configure

After installing ELMAH , it will automatically update Web.Config file. If it's not so you can add following code to Web.Config file.

<configuration>
<configSections>
    <sectionGroup name="elmah">
      <section name="security" requirePermission="false" type="Elmah.SecuritySectionHandler, Elmah" />
      <section name="errorLog" requirePermission="false" type="Elmah.ErrorLogSectionHandler, Elmah" />
      <section name="errorMail" requirePermission="false" type="Elmah.ErrorMailSectionHandler, Elmah" />
      <section name="errorFilter" requirePermission="false" type="Elmah.ErrorFilterSectionHandler, Elmah" />
    </sectionGroup>
</configSections>

<system.web>   
    <httpModules>
      <add name="ErrorLog" type="Elmah.ErrorLogModule, Elmah" />
      <add name="ErrorMail" type="Elmah.ErrorMailModule, Elmah" />
      <add name="ErrorFilter" type="Elmah.ErrorFilterModule, Elmah" />
    </httpModules>
</system.web>

<system.webServer>
<modules>
      <add name="ErrorLog" type="Elmah.ErrorLogModule, Elmah" preCondition="managedHandler" />
      <add name="ErrorMail" type="Elmah.ErrorMailModule, Elmah" preCondition="managedHandler" />
      <add name="ErrorFilter" type="Elmah.ErrorFilterModule, Elmah" preCondition="managedHandler" />
</modules>
</system.webServer>
<elmah>
    <security allowRemoteAccess="false" />
    <errorLog type="Elmah.SqlErrorLog, Elmah" connectionStringName="YourConnectionStringName" />
</elmah>
    <location path="elmah.axd" inheritInChildApplications="false">
    <system.web>
      <httpHandlers>
        <add verb="POST,GET,HEAD" path="elmah.axd" type="Elmah.ErrorLogPageFactory, Elmah" />
      </httpHandlers>
      <!--
      <authorization>
        <allow roles="admin" />
        <deny users="*" /> 
      </authorization>
      --> 
    </system.web>
    <system.webServer>
      <handlers>
        <add name="ELMAH" verb="POST,GET,HEAD" path="elmah.axd" type="Elmah.ErrorLogPageFactory, Elmah" preCondition="integratedMode" />
      </handlers>
    </system.webServer>
  </location>
</configuration>
Usage Now, It's time to use and test elmah for application. Generate exception in Home Controller
public ActionResult Index()
{
   throw new Exception("This is test Exception");
          
   return View();
}


after generating exception check your elmah like http://www.example.com/elmah.axd
Here is our output

integrate-elmah-in-aspnet-mvc

integrate elmah in asp. net mvc

Security

In addition ELMAH provides seamless security feature to prevent unauthorized access. Please read our next article to make your elmah secure.

Filtering

ELMAH identify and store exceptions in different category, you can make or edit ELMAH error screen with different filters which we will discuss in our next ELMAH series.

Notification

You can setup ELMAH email notification when any exception occurs. To unable notification option you must include below code

Add ErrorMail module
<httpModules>
    <add name="ErrorMail" type="Elmah.ErrorMailModule, Elmah"/>
</httpModules>


Add SMTP Setting
<system.net>
    <mailSettings>
        <smtp deliveryMethod="network">
            <network host="..." port="25" userName="..." password="..." />
        </smtp>
    </mailSettings>
</system.net>
 

or
<elmah>
<errorMail from="..." to="..."  async="true" smtpServer="..." smtpPort="25" userName="..." password="..." />
</elmah>

 

 


HostForLIFE.eu ASP.NET MVC Hosting
HostForLIFE.eu is European Windows Hosting Provider which focuses on Windows Platform only. We deliver on-demand hosting solutions including Shared hosting, Reseller Hosting, Cloud Hosting, Dedicated Servers, and IT as a Service for companies of all sizes. We have customers from around the globe, spread across every continent. We serve the hosting needs of the business and professional, government and nonprofit, entertainment and personal use market segments.

 



ASP.NET MVC Hosting - HostForLIFE.eu :: How To Make Simple Application In ASP.NET MVC Using Select2?

clock June 6, 2016 23:46 by author Anthony

In this tutorial, I will show you how to make simple application in ASP.NET MVC using Select2. The infinite scrolling feature has also been implemented with server side options population. Select2 is very useful for dropdown lists with large datasets.

Why Select2 :

  • Using this jQuery plugin for dropdown lists, you can implement features such as option grouping, searching, infinite scrolling, tagging, remote data sets and other highly used features.
  • To use select2 in web projects, you just have to include JavaScript and CSS files of Select2 in your website.
  • Current version of select2 is 4.0.0. You can easily include these files by installation of NuGet package ‘Select2.js’ from NuGet package manager.

Steps of Implementation:
1. Create a blank ASP.NET MVC project, and install NuGet packages Select2.js, jQuery and jQuery Unobtrusive.
2. Add one controller with the name ‘HomeController’ and add view for default method ‘Index’.
3. Create new class in Models folder ‘IndexViewModel.cs as shown below:

public class IndexViewModel
{
   [Required(ErrorMessage="Please select any option")]
   public string OptionId { get; set; }
}

4. Bind ‘Index.cshtml’ view with IndexViewModelClass as model, by adding the following line in Index view:

@model Select2InMvcProject.Models.IndexViewModel

5. In ‘Index.cshtml’, include the css and js files below:

<link href="~/Content/css/select2.css" rel="stylesheet" />
<script src="~/Scripts/jquery-2.1.4.js"></script>
<script src="~/Scripts/select2.js"></script>
<script src="~/Scripts/jquery.validate.js"></script>
<script src="~/Scripts/jquery.validate.unobtrusive.js"></script>


6. Write the following code in the Index view for creation of select list:

@using (Html.BeginForm())
{
   <br /><br />
   @Html.DropDownListFor(n => n.OptionId, Enumerable.Empty<SelectListItem>(), new { @id = "txtOptionId", @style = "width:300px;" })
//Created selectlist with empty enumerable of SelectListItem and given //id as “txtOptionId”
   @Html.ValidationMessageFor(n => n.OptionId)
//Adds span of validation error message
   <br /><br />
<button type="submit">Submit</button>
   <br /><br />
}


7. For applying Select2 to the dropdown list created above, fetching data from server side and for infinite scroll, use the jQuery code below in Index view:

<script type="text/javascript">
   $(document).ready(function () {
       var pageSize = 20;
       var optionListUrl = '@Url.Action("GetOptionList", "Home")';
//Method which is to be called for populating options in dropdown //dynamically
       $('#txtOptionId').select2(
       {
           ajax: {
               delay: 150,
               url: optionListUrl,
               dataType: 'json',
               data: function (params) {
                   params.page = params.page || 1;
                   return {
                       searchTerm: params.term,
                       pageSize: pageSize,
                       pageNumber: params.page
                   };
               },
               processResults: function (data, params) {
                   params.page = params.page || 1;
                  return {
                       results: data.Results,
                       pagination: {
                           more: (params.page * pageSize) < data.Total
                       }
                   };
               }
           },
           placeholder: "-- Select --",
           minimumInputLength: 0,
           allowClear: true,
   });
});
</script>


8. Create new class in Models folder with name ‘Select2OptionModel’ and add the two classes below:

public class Select2OptionModel
{
       public string id { get; set; }
       public string text { get; set; }
}
public class Select2PagedResult
{
       public int Total { get; set; }
       public List<Select2OptionModel> Results { get; set; }
}


9. Create one new folder with name ‘Repository’ in the solution, and add new class in that folder with name ‘Select2Repository. The functions in this class are mentioned below:

public class Select2Repository
   {
       IQueryable<Select2OptionModel> AllOptionsList;
public Select2Repository()
{
           AllOptionsList = GetSelect2Options();
}
IQueryable<Select2OptionModel> GetSelect2Options()
                  {
                                     string cacheKey = "Select2Options";
                                     //check cache
                                     if (HttpContext.Current.Cache[cacheKey] != null)
                                     {
return (IQueryable<Select2OptionModel>)HttpContext.Current.Cache[cacheKey];
                                     }
                                     var optionList = new List<Select2OptionModel>();
                                     var optionText = "Option Number ";
                                     for (int i = 1; i < 1000; i++)
                                     {
                                     optionList.Add(new Select2OptionModel
                                     {
                                               id = i.ToString(),
                                               text = optionText + i
                                     });
                                   }
                                   var result = optionList.AsQueryable();
                                     //cache results
                                     HttpContext.Current.Cache[cacheKey] = result;
                                     return result;}
 
List<Select2OptionModel> GetPagedListOptions(string searchTerm, int pageSize, int pageNumber, out int totalSearchRecords)
                  {
                                     var allSearchedResults = GetAllSearchResults(searchTerm);
                                     totalSearchRecords = allSearchedResults.Count;
return allSearchedResults.Skip((pageNumber - 1) * pageSize).Take(pageSize).ToList();
                  }
                  List<Select2OptionModel> GetAllSearchResults(string searchTerm)
                  {

                                     var resultList = new List<Select2OptionModel>();
                                      if (!string.IsNullOrEmpty(searchTerm))
resultList = AllOptionsList.Where(n => n.text.ToLower().Contains(searchTerm.ToLower())).ToList();
                                     else
                                     resultList = AllOptionsList.ToList();
                                     return resultList;
                  }
                  public Select2PagedResult GetSelect2PagedResult(string searchTerm, int pageSize, int pageNumber)
                  {
                                     var select2pagedResult = new Select2PagedResult();
                                     var totalResults = 0;
                                     select2pagedResult.Results = GetPagedListOptions(searchTerm,
pageSize, pageNumber, out totalResults);
                                     select2pagedResult.Total = totalResults;
                                     return select2pagedResult;
}
}

10.  In HomeController class, create new method as shown below:

public JsonResult GetOptionList(string searchTerm, int pageSize, int pageNumber)
{
     var select2Repository = new Select2Repository();
     var result = select2Repository.GetSelect2PagedResult(searchTerm, pageSize, pageNumber);
     return Json(result, JsonRequestBehavior.AllowGet);
}

11. Once you are done with coding, you can build and run the project. The output will be shown as below:

dropdown1.png

dropdown2.png


HostForLIFE.eu ASP.NET MVC Hosting
HostForLIFE.eu is European Windows Hosting Provider which focuses on Windows Platform only. We deliver on-demand hosting solutions including Shared hosting, Reseller Hosting, Cloud Hosting, Dedicated Servers, and IT as a Service for companies of all sizes. We have customers from around the globe, spread across every continent. We serve the hosting needs of the business and professional, government and nonprofit, entertainment and personal use market segments.

 



ASP.NET MVC 6 Hosting - HostForLIFE.eu :: How To Create Google Maps Sample App ASP.NET MVC And AngularJS

clock May 30, 2016 21:03 by author Anthony

Today I am going to explain how to create Google Maps Sample App with AngularJS and asp.net MVC. In one of the previous article, we have seen How to display google map in asp.net application andHow to load GMap Direction from database in ASP.NET using google map.

In order to use the Google Maps in our application, we need to add the following resources: 

  • angular.js
  • lodash.js - Loadash is a dependency of angular-google-maps library.
  • angular-google-maps.js - Angular Google Maps is a set of directives which integrate Google Maps in an AngularJS applications.

Just follow the following steps in order to create a sample google app with AngularJS and asp.net MVC:

Step - 1: Create New Project.

Go to File > New > Project > Select asp.net MVC4 web application > Entry Application Name > Click OK > Select Basic > Select view engine Razor > OK 

Step-2: Add a Database.

Go to Solution Explorer > Right Click on App_Data folder > Add > New item > Select SQL Server Database Under Data > Enter Database name > Add. Here I have added a database for store some location information in our database for show in the google map.  

Step-3: Create a table.

Here I will create 1 table (as below) for store location information. Open Database > Right Click on Table > Add New Table > Add Columns > Save > Enter table name > Ok. 

Step-4: Add Entity Data Model.

Go to Solution Explorer > Right Click on Project name form Solution Explorer > Add > New item > Select ADO.net Entity Data Model under data > Enter model name > Add. A popup window will come (Entity Data Model Wizard) > Select Generate from database > Next > Chose your data connection > select your database > next > Select tables > enter Model Namespace > Finish. 

Step-5: Create a Controller.

Go to Solution Explorer > Right Click on Controllers folder form Solution Explorer > Add > Controller > Enter Controller name > Select Templete "empty MVC Controller"> Add. Here I have created a controller "HomeController" 

Step-6: Add new action into the controller to get the view where we will show google map

Here I have added "Index" Action into "Home" Controller. Please write this following code 

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

Step-7: Add another action (here "GetAllLocation") for fetch all the location from the database.

public JsonResult GetAllLocation()
{   
using (MyDatabaseEntities dc = new MyDatabaseEntities())   
{       
var v = dc.Locations.OrderBy(a => a.Title).ToList();      
return new JsonResult { Data = v, JsonRequestBehavior = JsonRequestBehavior.AllowGet };
}
}

Step-8: Add 1 more action (here "GetMarkerInfo") for getting google marker information from the database to show in the map.

public JsonResult GetMarkerInfo(int locationID)
{    using (MyDatabaseEntities dc = new MyDatabaseEntities())
    {        Location l = null;
        l = dc.Locations.Where(a => a.LocationID.Equals(locationID)).FirstOrDefault();
        return new JsonResult { Data = l, JsonRequestBehavior = JsonRequestBehavior.AllowGet };
}
}

Step-9: Add a new javascript file, will contain all the necessary logic to implement our Google Map.

Right Click on Action Method (here right click on Index action) > Add View... > Enter View Name > Select View Engine (Razor) > Add. 

var app = angular.module('myApp', ['uiGmapgoogle-maps']);
app.controller('mapController', function ($scope, $http) {
     //this is for default map focus when load first time
    $scope.map = { center: { latitude: 22.590406, longitude: 88.366034 }, zoom: 16 }
     $scope.markers = [];
    $scope.locations = [];
    //Populate all location
    $http.get('/home/GetAllLocation').then(function (data) {
        $scope.locations = data.data;
    }, function () {
        alert('Error');
    });
    //get marker info
    $scope.ShowLocation = function (locationID) {
        $http.get('/home/GetMarkerInfo', {
            params: {
                locationID: locationID
            }
        }).then(function (data) {
            //clear markers
            $scope.markers = [];
            $scope.markers.push({
                id: data.data.LocationID,
                coords: { latitude: data.data.Lat, longitude: data.data.Long },
                title: data.data.title,               
                address: data.data.Address,                               
                image : data.data.ImagePath           
});
            //set map focus to center
            $scope.map.center.latitude = data.data.Lat;
            $scope.map.center.longitude = data.data.Long;
        }, function () {
            alert('Error');
        });
    }
    //Show / Hide marker on map
    $scope.windowOptions = {
        show: true
    };
}); 

Step-10: Add view for the action (here "Index") & design.

Right Click on Action Method (here right click on Index action) > Add View... > Enter View Name > Select View Engine (Razor) > Add. HTML Code 

@{    ViewBag.Title = "Index";
}
<h2>Index</h2>
<div ng-app="myApp" ng-controller="mapController">
    <div class="locations">
        <ul>
            <li ng-repeat="l in locations" ng-click="ShowLocation(l.LocationID)">{{l.Title}}</li>
        </ul>
    </div>
    <div class="maps">
        <!-- Add directive code (gmap directive) for show map and markers-->
        <ui-gmap-google-map center="map.center" zoom="map.zoom">
            <ui-gmap-marker ng-repeat="marker in markers" coords="marker.coords" options="marker.options" events="marker.events" idkey="marker.id">
                <ui-gmap-window options="windowOptions" show="windowOptions.show">
                    <div style="max-width:200px">
                        <div class="header"><strong>{{marker.title}}</strong></div>
                        <div id="mapcontent">
                            <p>
                                <img ng-src="{{marker.image}}" style="width:200px; height:100px" />
                                <div>{{marker.address}}</div>
                            </p>
                        </div>
                    </div>
                </ui-gmap-window>
            </ui-gmap-marker>
        </ui-gmap-google-map>
    </div>
</div>
@* Now here we need to some css and js *@
<style>
    .angular-google-map-container {
        height:300px;
    }
    .angular-google-map {
        width:80%;
        height:100%;
        margin:auto 0px;
    }
    .locations {
        width: 200px;
        float: left;
    }
    .locations ul {
        padding: 0px;
        margin: 0px;
        margin-right: 20px;
    }
    .locations ul li {
        list-style-type: none;
        padding: 5px;
        border-bottom: 1px solid #f3f3f3;
        cursor: pointer;
    }
</style>
@section Scripts{
    @* AngularJS library *@
    <script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.6/angular.js"></script>
    @* google map directive js *@
    <script src="//cdnjs.cloudflare.com/ajax/libs/lodash.js/2.4.1/lodash.js"></script>
    <script src="//rawgit.com/angular-ui/angular-google-maps/2.0.X/dist/angular-google-maps.js"></script>
    @* here We will add our created js file *@
    <script src="~/Scripts/ngMap.js"></script>
}

Step-11: Run Application.


HostForLIFE.eu ASP.NET MVC 6 Hosting
HostForLIFE.eu is European Windows Hosting Provider which focuses on Windows Platform only. We deliver on-demand hosting solutions including Shared hosting, Reseller Hosting, Cloud Hosting, Dedicated Servers, and IT as a Service for companies of all sizes. We have customers from around the globe, spread across every continent. We serve the hosting needs of the business and professional, government and nonprofit, entertainment and personal use market segments.

 



ASP.NET MVC 6 Hosting - HostForLIFE.eu :: TempData in ASP.NET MVC 6

clock May 25, 2016 19:18 by author Anthony

In this Article, we will discuss about TempData. TempData in ASP.NET MVC can be used to store temporary data which can be used in the subsequent request. TempData will be cleared out after the completion of a subsequent request.

TempData is useful when you want to transfer non-sensitive data from one action method to another action method of the same or a different controller as well as redirects. It is dictionary type which is derived from TempDataDictionary.

You can add a key-value pair in TempData as shown in the below example.

TempData allows you to store data & it will remain after redirects. It uses the Session to store data. When an object in a TempDataDictionary. It will be marked for deletion at the end of that request.

TempData declared as

TempData["value"] = "data";

Example


public ActionResult FirstAction()

{
    // store something into the tempdata that will be available during a single redirect
    TempData["FirstAction"] = "SecondAction";
    // you should always redirect if you store something into TempData to
    // a controller action that will consume this data
    return RedirectToAction("SecondAction");
}
public ActionResult SecondAction()
{    var data = TempData["FirstAction"];
   return View();
}

 
The Peek and Keep methods allow to read the value without deletion. we can say that first request data will remains in TempData. You can use Peek when you always want to retain the value for another request. Use Keep when retaining the value depends on additional logic.

//second request, Peek value is not deleted at the end of the request
object value = TempData.Peek("value");

//third request, read value and delete
object value = TempData["value"];

 

Keep

//second request, get value going for delete
object value = TempData.["value"];

//later  decide to keep it for next request
TempData.Keep("value");

//third request, read value and mark it for deletion
object value = TempData["value"];

Removing TempData

TempData.Clear() : It is use to remove all keys from the TempDataDictionary TempData.Remove(key) :Remove a specific key from TempDataDictionary.

Note: Since TempData makes use of the Session State behavior, it must be enabled on the controller using TempData. By default it is always enabled, You can disable session state for your controllers by adding [SessionState(SessionStateBehavior.Disabled)] attribute .



HostForLIFE.eu ASP.NET MVC 6 Hosting
HostForLIFE.eu is European Windows Hosting Provider which focuses on Windows Platform only. We deliver on-demand hosting solutions including Shared hosting, Reseller Hosting, Cloud Hosting, Dedicated Servers, and IT as a Service for companies of all sizes. We have customers from around the globe, spread across every continent. We serve the hosting needs of the business and professional, government and nonprofit, entertainment and personal use market segments.



ASP.NET MVC 5 Hosting - HostForLIFE.eu :: AngularJS Login Page in ASP.NET MVC 5

clock May 17, 2016 23:45 by author Anthony

In this tutorial i am going to explain about how to create a login page using Angular js in MVC 5 application. In this tutorial i used Simple form validation using angular(we will discuss about angular validation in detail in future post).And also a $http angular built in service.

$http: It is a angular JS built in service for communicating with remote servers.In Angular all communications (Request and response) between server and client are handled by services like $http.

Step 1: Create a Data table in Database

1.Here i used Local Database for Table creation (Sql Express).
2.Right click server explorer --> expand Database --> Right click on tables --> Click Add new table.
3.Create a table with  following columns if you want you can add more columns.
4.Here i created following table.

Step 2: Add ADO.NET Entity Data Model

1.Right click on Models --> Add --> New Item -->Select ADO.NET Entity Data Model(Under Data) --> name it -->Add --> select Add from Database (In Entity Data Model wizard) --> Next
2.Select Database --> give name for web.config.
3.Choose your Database objects(tables) and click finish.


Step 3: Add a Model Class to Solution

1.Right click Models --> Add --> Class and name it (I named it as UserModel.cs).
2.These Model objects are useful while we sending data from View to Controller.
3.We bind this Model properties with angular ngModel.(you will see in index.cshtml).
4.replace code with following code

namespace LoginUsingAngular.Models
{
    public class UserModel
    {
        public string Email { get; set; }
        public string Password { get; set; }
    }
}

Step 4: Add New Action Method in HomeController to Check User Data

1.This Action Method gets data from database based on user entered data in form.and returns that data in Json format to angular Controller.
2.Add code in HomeController
getLoginData():

public ActionResult getLoginData(UserModel obj)
        {
            DatabaseEntities db = new DatabaseEntities();
            var user = db.Users.Where(x => x.Email.Equals(obj.Email) && x.Password.Equals(obj.Password)).FirstOrDefault();
            return new JsonResult {Data=user,JsonRequestBehavior=JsonRequestBehavior.AllowGet };
        }

Step 5: Add angular controller for checking Login Form

1.Create angular module in  Module.js file.
(function () {
    var myApp = angular.module("myApp",[]);
})();

2.Now add another script file for angular controller and Factory method.
3.Right click on Scripts folder --> add LoginController.js
4.Replace code in LoginController.js file.

angular.module('myApp').controller('LoginController', function ($scope, LoginService) {
 
        //initilize user data object
        $scope.LoginData = {
            Email: '',
            Password:''
        }
        $scope.msg = "";
        $scope.Submited = false;
        $scope.IsLoggedIn = false;
        $scope.IsFormValid = false;
 
        //Check whether the form is valid or not using $watch
        $scope.$watch("myForm.$valid", function (TrueOrFalse) {
            $scope.IsFormValid = TrueOrFalse;   //returns true if form valid
        });
 
        $scope.LoginForm = function () {
            $scope.Submited = true;
            if ($scope.IsFormValid) {
                LoginService.getUserDetails($scope.UserModel).then(function (d) {
                    debugger;
                    if (d.data.Email != null) {
                        debugger;
                        $scope.IsLoggedIn = true;
                        $scope.msg = "You successfully Loggedin Mr/Ms " +d.data.FullName;
                    }
                    else {
                        alert("Invalid credentials buddy! try again");
                    }
                });
            }
        }
    })
    .factory("LoginService", function ($http) {
        //initilize factory object.
        var fact = {};
        fact.getUserDetails = function (d) {
            debugger;
            return $http({
                url: '/Home/getLoginData',
                method: 'POST',
                data:JSON.stringify(d),
                headers: { 'content-type': 'application/json' }
            });
        };
        return fact;
    });


4.Here,I validated form using $watch in above code.
5.I created a angular service LoginService that gets data from server controller (from HomeController.getLoginData() action).
6.LoginForm() method is initiated when user submits form using ngSubmit as angular attribute.


Step 6: Add View to display Login Form

1.Right click on Index action --> Add View --> add
2.Replace Index.cshtml view code with following code

@{
    ViewBag.Title = "Login Using Angular";
}
<h2>Login Using Angular</h2>

<div ng-controller="LoginController">
    <form name="myForm" novalidate ng-submit="LoginForm()">
        <div style="color:green">{{msg}}</div>
        <table ng-show="!IsLoggedIn" class="table table-horizontal">
            <tr>
                <td>Email/UserName :</td>
                <td>
                    <input type="email" ng-model="UserModel.Email" name="UserEmail" ng-class="Submited?'ng-dirty':''" required autofocus class="form-control"/>
                    <span style="color:red" ng-show="(myForm.UserEmail.$dirty || Submited ) && myForm.UserEmail.$error.required">Please enter Email</span>
                    <span style="color:red" ng-show="myForm.UserEmail.$error.email">Email is not valid</span>
                </td>
            </tr>
            <tr>
                <td>Password :</td>
                <td>
                    <input type="password" ng-model="UserModel.Password" name="UserPassword" ng-class="Submited?'ng-dirty':''" required autofocus class="form-control"/>
                    <span style="color:red" ng-show="(myForm.UserPassword.$dirty || Submited) && myForm.UserPassword.$error.required">Password Required</span>
                </td>
            </tr>
            <tr>
                <td></td>
                <td>
                    <input type="submit" value="submit" class="btn btn-success" />
                </td>
            </tr>
        </table>
    </form>
</div>
@section scripts{
    <script src="~/Scripts/LoginController.js"></script>
}

Add script reference at the end of Index.cshtml page.
Take a look at following things i used in above Index.cshtml view.

ng-Model: ngModel is a angular directive.it is used for two way binding data from view to controller and controller to view.In above example i used it to bind from data to angular controller.

ng-show: ngShow allows to display or hide elements based on the expression provided to ngShow attribute.

ng-submit:  ng-submit prevents the default action of form and binds angular function to onsubmit events. This is invoked when form is submitted.

$dirty: It is angular built in property. It will be true if user interacted with form other wise false.This is one of the angular validation property i used in above example.There are many validation properties in angular like $invalid,$submitted,$pristine,$valid and $error.We will learn about all these these properties in later tutorials.

 




ASP.NET MVC 6 Hosting - HostForLIFE.eu :: How to Make ASP.NET MVC 6 View Injection?

clock May 5, 2016 00:10 by author Anthony

ASP.NET MVC 6, a new feature called view components has been introduced. View components are similar to child actions and partials views, allowing you to create reusable components with (or without) logic. Here's the summary from the ASP.NET documentation:


View components include the same separation-of-concerns and testability benefits found between a controller and view. You can think of a view component as a mini-controller—it’s responsible for rendering a chunk rather than a whole response. You can use view components to solve any problem that you feel is too complex with a partial.


Before ASP.NET Core, you would've probably used a child action to create a reusable component that requires some code for its logic. ASP.NET MVC 6, however, doesn't have child actions anymore. You can now choose between a partial view or a view component, depending on the requirements for the feature you're implementing.

Writing A Simple View Component

Let's implement a simple dynamic navigation menu as a view component. We want to be able to display different navigation items based on some conditional logic (e.g. the user's claims or the hosting environment). Like controllers, view components must be public, non-nested, and non-abstract classes that either

  • derive from the ViewComponent class,
  • are decorated with the [ViewComponent] attribute, or
  • have a name that ends with the "ViewComponent" suffix.

We'll choose the base class approach because ViewComponent provides a bunch of helper methods that we'll be calling to return and render a chunk of HTML.


ASP.NET MVC 6 Dependency Injection using a simple container that is bundled with ASP.NET MVC 6. This is great for injecting dependencies into controllers, filters, etc. In this tutorial I mention the new inject keyword that can be added to razor views for injecting dependencies into views.


Registering Service

First, we have to register the service with the IoC container built into ASP.NET MVC 6.

public void ConfigureServices(IServiceCollection services) {
    ...
    services.AddTransient<ITestService, TestService>();
}

This is no different from the previous example: ASP.NET MVC 6 Dependency Injection.

Inject Keyword for Razor Views


Next we can inject the the service for use in the razor view using the new inject keyword.

@inject ITestService testService


Now the service is available to our view and can be used appropriately anywhere in the view.

@using Sample.Services
@inject ITestService testService
<p>So I looked down and said... @testService.WhatAreThose()</p>

Conclusion

Injecting dependencies in ASP.NET MVC 6 views using the new inject keyword can make things quite a bit easier. Now that ASP.NET MVC 6 has a basic IoC container we'll probably see more people start to use dependency injection not only in their views, but also in their controllers, filters, services, etc.




ASP.NET MVC 5 Hosting - HostForLIFE.eu :: How To Create Area?

clock April 28, 2016 20:59 by author Anthony

Today, you will learn how to create Area in MVC 5. In MVC 5 (Visual Studio 2013), Area option can be found under ‘Add Scaffold’ dialog. In this post, I will take you through step by step to setup and running Area in MVC 5.


As you know MVC Architecture separates all the logics: model logic, business logic and presentation logic and provides a very clean and light weight application in total. One more good thing that I love is, it provides logical separation physically also. In physical logic separation controllers, models and views are kept in another folder on root with the help of Area. Areas provide a way to separate a large MVC Web Application into smaller functional groupings inside MVC Application and each group contains MVC Structure (Ex. Model, View and Controller folders). Area was introduced with MVC 2 release.

Assume, you are working on a MVC Project where you have a requirement  to develop various sections like account section, administrative section, support section, billing section and so on. Area is the best choice here, it will provide a strong physical structure as well as better code manageability. See how it looks like.

 


You can see every section has MVC Architecture Controller, Model, View (view will have a Shared folder where you can place your layouts, partial views etc) and an AreaRegistration (which contains RegisterArea method very similar to RegisterRoutes).

How to Create It

We are going to create CRUD views for Employee inside Area. We will take the advantage of EF Code First. Let’s walk through the simple steps. In Visual Studio 2012 IDE (MVC 4), we just right click on Project | Add | Area to create Area.

 

Step 1


Right click on Project and then select Add | Scaffold | MVC 5 Area.

Step 2

When we click on ‘Scaffold’ it opens a dialog where we need to select MVC 5 Area and hit on Add button, it will ask to enter area name, type ‘Admin’ and hit Add.
Do the same to add Area for Billing and Support, at the end we will have following structure.



 

Now once we are done with adding areas, go to next step.

Step 3


In above step we added three Areas, in each area we will find a class file areanameAreaRegistration.cs file, open this file, we will find following RegisterArea method inside class which inherits AreaRegistration class.

public override void RegisterArea(AreaRegistrationContext context)
{
    context.MapRoute(
        "Billing_default",
        "Admin/{controller}/{action}/{id}",
        new { action = "Index", id = UrlParameter.Optional }
    );
}


Look at this root closely, we will find this route begins with Admin and then controller, action and id (which is marked as optional).


We will find same thing in other Area also.

In total we have three areanameAreaRegistration.cs classes all inherits AreaRegistration class, and also a route defined for the Area. These routes should be registered inside Application_Start() method of Global.asax file, here is the code.

protected void Application_Start()
{
    AreaRegistration.RegisterAllAreas();

    FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
    RouteConfig.RegisterRoutes(RouteTable.Routes);
    BundleConfig.RegisterBundles(BundleTable.Bundles);
}


Now, let’s go in next step where we will create CRUD views and see how it opens in browser.


Step 4


Once we have done with previous steps, just go ahead and add model, controller and views to see how area opens in browser. We could and anything we want but just to keep things simple I am going to create a CRUD in Admin Area for Employee, here is the model I will be using.

public class Employee
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Address { get; set; }
}

Now, create CRUD views and browse it.

Look at the URL in above image you will see the first segment ‘Admin’ is area name, second segment ‘Employee’ is controller, third segment ‘Details’ is action result and fourth segment ‘1’ is ID.


So, you can see how Area is working in MVC 5. There is no difference in ‘Area in MVC 4’ and ‘Area in MVC 5’, things are still same, the only change is the way Area added, that’s it.

 

HostForLIFE.eu ASP.NET MVC 5 Hosting
HostForLIFE.eu revolutionized hosting with Plesk Control Panel, a Web-based interface that provides customers with 24x7 access to their server and site configuration tools. Plesk completes requests in seconds. It is included free with each hosting account. Renowned for its comprehensive functionality - beyond other hosting control panels - and ease of use, Plesk Control Panel is available only to HostForLIFE's customers. They
offer a highly redundant, carrier-class architecture, designed around the needs of shared hosting customers.

http://aspnetmvceuropeanhosting.hostforlife.eu/image.axd?picture=2015%2f10%2fhostforlifebanner.png



ASP.NET MVC 5 Hosting - HostForLIFE.eu :: How to Handle ASP.NET MVC 5 Errors?

clock April 27, 2016 23:38 by author Anthony

Custom error pages and global error logging are two elementary and yet very confusing topics in ASP.NET MVC 5.

There are numerous ways of implementing error pages in ASP.NET MVC 5 and when you search for advice you will find a dozen different StackOverflow threads, each suggesting a different implementation.

Overview

What is the goal?


Typically good error handling consists of:

  • Human friendly error pages
    • Custom error page per error code (e.g.: 404, 403, 500, etc.)
    • Preserving the HTTP error code in the response to avoid search engine indexing
  • Global error logging for unhandled exceptions

Error pages and logging in ASP.NET MVC 5


There are many ways of implementing error handling in ASP.NET MVC 5. Usually you will find solutions which involve at least one or a combination of these methods:

  • HandleErrorAttribute
  • Controller.OnException Method
  • Application_Error event
  • CustomErrors element in web.config
  • httpErrors element in web.config
  • Custom HttpModule

All these methods have a historical reason and a justifyable use case. There is no golden solution which works for every application. It is good to know the differences in order to better understand which one is applied best.

Before going through each method in more detail I would like to explain some basic fundamentals which will hopefully help in understanding the topic a lot easier.

ASP.NET MVC Fundamentals


The MVC framework is only a HttpHandler plugged into the ASP.NET pipeline. The easiest way to illustrate this is by opening the Global.asax.cs:

public class MvcApplication : System.Web.HttpApplication
Navigating to the implementation of HttpApplication will reveal the underlying IHttpHandler and IHttpAsyncHandler interfaces:

public class HttpApplication : IComponent, IDisposable, IHttpAsyncHandler, IHttpHandler
ASP.NET itself is a larger framework to process incoming requests. Even though it could handle incoming requests from different sources, it is almost exclusively used with IIS. It can be extended with HttpModules and HttpHandlers.

HttpModules are plugged into the pipeline to process a request at any point of the ASP.NET life cycle. A HttpHandler is responsible for producing a response/output for a request.

IIS (Microsoft's web server technology) will create an incoming request for ASP.NET, which subsequently will start processing the request and eventually initialize the HttpApplication (which is the default handler) and create a response:

IIS, ASP.NET and MVC architecture

The key thing to know is that ASP.NET can only handle requests which IIS forwards to it. This is determined by the registered HttpHandlers (e.g. by default a request to a .htm file is not handled by ASP.NET).

And finally, MVC is only one of potentially many registered handlers in the ASP.NET pipeline.

This is crucial to understand the impact of different error handling methods.

Breaking down the options


HandleErrorAttribute

The HandleErrorAttribute is an MVC FilterAttribute, which can be applied to a class or a method:

namespace System.Web.Mvc
{
    [AttributeUsage(
        AttributeTargets.Class | AttributeTargets.Method,
        Inherited = true,
        AllowMultiple = true)]
    public class HandleErrorAttribute : FilterAttribute, IExceptionFilter
    {
        // ...
    }
}

It's error handling scope is limited to action methods within the MVC framework. This means it won't be able to catch and process exceptions raised from outside the ASP.NET MVC handler (e.g. exceptions at an earlier stage in the life cycle or errors in other handlers). It will equally not catch an exception if the action method is not part of the call stack (e.g. routing errors).

Additionally the HandleErrorAttribute only handles 500 internal server errors. For instance this will not be caught by the attribute:

[HandleError]
public ActionResult Index()
{
    throw new HttpException(404, "Not found");
}

You can use the attribute to decorate a controller class or a particular action method. It supports custom error pages per exception type out of the box:

[HandleError(ExceptionType = typeof(SqlException), View = "DatabaseError")]]
In order to get the HandleErrorAttribute working you also need to turn customErrors mode on in your web.config:

<system.web>
    <customErrors mode="On" />
</system.web>

Use case

The HandleErrorAttribute is the most limited in scope. Many application errors will bypass this filter and therefore it is not ideal for global application error handling.

It is a great tool for action specific error handling like additional fault tolerance for a critical action method though.

Controller.OnException Method


The OnException method gets invoked if an action method from the controller throws an exception. Unlike the HandleErrorAttribute it will also catch 404 and other HTTP error codes and it doesn't require customErrors to be turned on.

It is implemented by overriding the OnException method in a controller:

protected override void OnException(ExceptionContext filterContext)
{
    filterContext.ExceptionHandled = true;
           
    // Redirect on error:
    filterContext.Result = RedirectToAction("Index", "Error");

    // OR set the result without redirection:
    filterContext.Result = new ViewResult
    {
        ViewName = "~/Views/Error/Index.cshtml"
    };
}

With the filterContext.ExceptionHandled property you can check if an exception has been handled at an earlier stage (e.g. the HandleErrorAttribute):

if (filterContext.ExceptionHandled)
    return;

Many solutions on the internet suggest to create a base controller class and implement the OnException method in one place to get a global error handler.

However, this is not ideal because the OnException method is almost as limited as the HandleErrorAttribute in its scope. You will end up duplicating your work in at least one other place.

Use case


The Controller.OnException method gives you a little bit more flexibility than the HandleErrorAttribute, but it is still tied to the MVC framework. It is useful when you need to distinguish your error handling between regular and AJAX requests on a controller level.

Application_Error event


The Application_Error method is far more generic than the previous two options. It is not limited to the MVC scope any longer and needs to be implemented in the Global.asax.cs file:

protected void Application_Error(Object sender, EventArgs e)
{
    var raisedException = Server.GetLastError();

    // Process exception
}

If you've noticed it doesn't come from an interface, an abstract class or an overriden method. It is purely convention based, similar like the Page_Load event in ASP.NET Web Forms applications.

Any unhandeled exception within ASP.NET will bubble up to this event. There is also no concept of routes anymore (because it is outside the MVC scope). If you want to redirect to a specific error page you have to know the exact URL or configure it to co-exist with "customErrors" or "httpErrors" in the web.config.

Use case


In terms of global error logging this is a great place to start with! It will capture all exceptions which haven't been handled at an earlier stage. But be careful, if you have set filterContext.ExceptionHandled = true in one of the previous methods then the exception will not bubble up to Application_Error.

However, for custom error pages it is still not perfect. This event will trigger for all ASP.NET errors, but what if someone navigates to a URL which isn't handled by ASP.NET? For example try navigating to http://{your-website}/a/b/c/d/e/f/g. The route is not mapped to ASP.NET and therefore the Application_Error event will not be raised.

customErrors in web.config


The "customErrors" setting in the web.config allows to define custom error pages, as well as a catch-all error page for specific HTTP error codes:

<system.web>
    <customErrors mode="On" defaultRedirect="~/Error/Index">
        <error statusCode="404" redirect="~/Error/NotFound"/>
        <error statusCode="403" redirect="~/Error/BadRequest"/>
    </customErrors>
<system.web/>

By default "customErrors" will redirect a user to the defined error page with a HTTP 302 Redirect response. This is really bad practise because the browser will not receive the appropriate HTTP error code and redirect the user to the error page as if it was a legitimate page. The URL in the browser will change and the 302 HTTP code will be followed by a 200 OK, as if there was no error. This is not only confusing but has also other negative side effects like Google will start indexing those error pages.

You can change this behaviour by setting the redirectMode to "ResponseRewrite":

<customErrors mode="On" redirectMode="ResponseRewrite">

This fixes the initial problem, but will give a runtime error when redirecting to an error page now:

Runtime Error

An exception occurred while processing your request. Additionally, another exception occurred while executing the custom error page for the first exception. The request has been terminated.
This happens because "ResponseRewrite" mode uses Server.Transfer under the covers, which looks for a file on the file system. As a result you need to change the redirect path to a static file, for example to an .aspx or .html file:

<customErrors mode="On" redirectMode="ResponseRewrite" defaultRedirect="~/Error.aspx"/>
Now there is only one issue remaining with this configuration. The HTTP response code for the error page is still "200 OK". The only way to fix this is to manually set the correct error code in the .aspx error page:

<% Response.StatusCode = 404; %>
This is already pretty good in terms of custom error pages, but we can do better!

Noticed how the customErrors section goes into the system.web section? This means we are still in the scope of ASP.NET.

Files and routes which are not handled by your ASP.NET application will render a default 404 page from IIS (e.g. try http://{your-website}/not/existing/image.gif).

Another downside of customErrors is that if you use a HttpStatusCodeResult instead of throwing an actual exception then it will bypass the ASP.NET customErrors mode and go straight to IIS again:

public ActionResult Index()
{
    return HttpNotFound();
    //throw new HttpException(404, "Not found");
}

In this case there is no hack which can be applied to display a friendly error page which comes from customErrors.

Use case


The customErrors setting was for a long time the best solution, but still had its limits. You can think of it as a legacy version of httpErrors, which has been only introduced with IIS 7.0.

The only time when customErrors still makes sense is if you can't use httpErrors, because you are running on IIS 6.0 or lower.

httpErrors in web.config

The httpErrors section is similar to customErrors, but with the main difference that it is an IIS level setting rather than an ASP.NET setting and therefore needs to go into the system.webserver section in the web.config:

<system.webServer>
    <httpErrors errorMode="Custom" existingResponse="Replace">
      <clear/>
      <error
        statusCode="404"
        path="/WebForms/Index.aspx"
        responseMode="ExecuteURL"/>
    </httpErrors>
<system.webServer/>

It allows more configuration than customErrors but has its own little caveats. I'll try to explain the most important settings in a nutshell:

httpErrors can be inherited from a higher level (e.g. set in the machine.config)
Use the <remove/> tag to remove an inherited setting for a specific error code.
Use the <clear/> tag to remove all inherited settings.
Use the <error/> tag to configure the behaviour for one error code.
responseMode "ExecuteURL" will render a dynamic page with status code 200.
The workaround to set the correct error code in the .aspx page works here as well.
responseMode "Redirect" will redirect with HTTP 302 to a URL.
responseMode "File" will preserve the original error code and output a static file.
.aspx files will get output in plain text.
.html files will render as expected.
The main advantage of httpErrors is that it is handled on an IIS level. It will literally pick up all error codes and redirect to a friendly error page. If you want to benefit from master pages I would recommend to go with the ExecuteURL approach and status code fix. If you want to have rock solid error pages which IIS can serve even when everything else burns, then I'd recommend to go with the static file approach (preferably .html files).

Use case


This is currently the best place to configure friendly error pages in one location and to catch them all. The only reason not to use httpErrors is if you are still running on an older version of IIS (< 7.0).

Custom HttpModule


Last but not least I would like to quickly touch on custom HttpModules in ASP.NET. A custom HttpModule is not very useful for friendly error pages, but it is a great location to put global error logging in one place.

With a HttpModule you can subscribe to the OnError event of the HttpApplication object and this event behaves same way as the Application_Error event from the Global.asax.cs file. However, if you have both implemented then the one from the HttpModule gets called first.

The benefit of the HttpModule is that it is reusable in other ASP.NET applications. Adding/Removing a HttpModule is as simple as adding or removing one line in your web.config:

<system.webServer>
    <modules>
        <add name="CustomModule" type="SampleApp.CustomModule, SampleApp"/>
    </modules>
</system.webSe
rver>

 

 


HostForLIFE.eu ASP.NET MVC 5 Hosting
HostForLIFE.eu revolutionized hosting with Plesk Control Panel, a Web-based interface that provides customers with 24x7 access to their server and site configuration tools. Plesk completes requests in seconds. It is included free with each hosting account. Renowned for its comprehensive functionality - beyond other hosting control panels - and ease of use, Plesk Control Panel is available only to HostForLIFE's customers. They
offer a highly redundant, carrier-class architecture, designed around the needs of shared hosting customers.

 



ASP.NET MVC 6 Hosting - HostForLIFE.eu :: How to Get Lookup Data in ASP.NET MVC 6?

clock April 21, 2016 23:06 by author Anthony

In this article, I will explain about getting lookup dataa into you view ASP.Net MVC 6. This is a super common problem I encounter when building ASP.net MVC applications. I have a form that has a drop down box. Not only do I need to select the correct item from the edit model to pick from the drop down but I need to populate the drop down with the possible values.



Over the years I've used two approaches to doing this. The first is to push into the ViewBag a list of values in the controller action. That looks like

public ActionResult Edit(int id){ 
    var model = repository.get(id);

    ViewBag.Provinces = provincesService.List();

    return View(model);
}
Then in the view you can retrieve this data and use it to populate the drop down. If you're using the HTML helpers then this looks like

@Html.DropDownListFor(x=>x.province, (IEnumerable<SelectListItem>)ViewBag.Provinces)
This becomes somewhat messy when you have a lot of drop downs on a page. For instance consider something like

public ActionResult Edit(int id){ 
  var model = repository.get(id);

    ViewBag.Provinces = provincesService.List();
    ViewBag.States = statesService.List();
    ViewBag.StreetDirections = streetDirectionsService.List();
    ViewBag.Countries = countriesService.List();
    ViewBag.Counties = countiesService.List();

    return View(model);
}

The work of building up the data in the model becomes the primary focus of the view. We could extract it to a method but then we have to go hunting to find the different drop downs that are being populated. An approach I've taken in the past is to annotate the methods with an action filter to populate the ViewBag for me. This makes the action look like

[ProvincesFilter]
[StatesFilter]
[StreetDirectionsFilter]
[CountriesFilter]
[CountiesFilter]
public ActionResult Edit(int id){ 
  var model = repository.get(id);
  return View(model);
}

One of the filters might look like

public override void OnActionExecuting(ActionExecutingContext filterContext) 
{
    var countries = new List<SelectListItem>();
    if ((countries = (filterContext.HttpContext.Cache.Get(GetType().FullName) as List<SelectListItem>)) == null)
    {
        countries = countriesService.List();
        filterContext.HttpContext.Cache.Insert(GetType().FullName, countries);
    }
    filterContext.Controller.ViewBag.Countries = countries;
    base.OnActionExecuting(filterContext);
}

This filter also adds a degree of caching to the request so that we don't have to keep bugging the database.

Keeping a lot of data in the view bag presents a lot of opportunities for error. We don't have any sort of intellisense with the dynamic view object and I frequently use the wrong name in the controller and view, by mistake. Finally building the drop down box using the HTML helper requires some nasty looking casting. Any time I cast I feel uncomfortable.

@Html.DropDownListFor(x=>x.province, (IEnumerable<SelectListItem>)ViewBag.Provinces)
Now a lot of people prefer transferring the data as part of the model; this is the second approach. There is nothing special about this approach you just put some collections into the model.

I've always disliked this approach because it mixes the data needed for editing with the data for the drop downs which is really incidental. This data seems like a view level concern that really doesn't belong in the view model. This is a bit of a point of contention and I've challenged more than one person to a fight to the death over this very thing.

So neither option is particularly palatable. What we need is a third option and the new dependency injection capabilities of ASP.net MVC open up just such an option: we can inject the data services directly into the view. This means that we can consume the data right where we retrieve it without having to hammer it into some bloated DTO. We also don't have to worry about annotating our action or filling it with junk view specific code.

To start let's create a really simple service to return states.

public interface IStateService 
{
    IEnumerable<State> List();
}

public class StateService : IStateService 
{
    public IEnumerable<State> List() {
        return new List<State>
        {
            new State { Abbreviation = "AK", Name = "Alaska" },
            new State { Abbreviation = "AL", Name = "Alabama" }
        };
    }
}

Umm, looks like we're down to only two states, sorry Kentucky.

Now we can add this to our container. I took a singleton approach and just registered a single instance in the Startup.cs.

services.AddInstance(typeof(IStateService), new StateService()); 
This is easily added the the view by adding

@inject ViewInjection.Services.IStateService StateService

As the first line in the file. Then the final step is to actually make use of the service to populate a drop down box:

<div class="col-lg-12"> 
        @Html.DropDownList("States", StateService.List().Select(x => new SelectListItem { Text = x.Name, Value = x.Abbreviation }))
</div> 

That's it! Now we have a brand new way of getting the data we need to the view without having to clutter up our controller with anything that should be contained in the view.

 


HostForLIFE.eu ASP.NET MVC 6 Hosting
European best, cheap and reliable ASP.NET hosting with instant activation. HostForLIFE.eu is #1 Recommended Windows and ASP.NET hosting in European Continent. With 99.99% Uptime Guaranteed of Relibility, Stability and Performace. HostForLIFE.eu security team is constantly monitoring the entire network for unusual behaviour. We deliver hosting solution including Shared hosting, Cloud hosting, Reseller hosting, Dedicated Servers, and IT as Service for companies of all size.

 



About HostForLIFE.eu

HostForLIFE.eu is European Windows Hosting Provider which focuses on Windows Platform only. We deliver on-demand hosting solutions including Shared hosting, Reseller Hosting, Cloud Hosting, Dedicated Servers, and IT as a Service for companies of all sizes.

We have offered the latest Windows 2012 Hosting, ASP.NET 4.5 Hosting, ASP.NET MVC 5 Hosting, and SQL 2014 Hosting.


Tag cloud

Sign in