Font awesome not working on IIS for ASP.NET MVC project

Here are things that you should be checking if your fontawesome is not working when you put your website on IIS.

enter image description here

Check 1: Check if all the fonts (.otf, .woff etc) are copied to the /font-awesome-4.2.0/fonts/ folder.

Check 2: Remove the fontawesome.css from your bundle and add it directly like <link href="~/Content/font-awesome-4.2.0/css/font-awesome.css" rel='stylesheet' type='text/css' />

Setting up Staging, QA and Live web configs with Visual Studio 2013

Step 1 : Open the Configuration Manager dialog.
enter image description here

Step 2 : Select “<New..”> option from the Active solution configuration dropdown.
enter image description here

Step 3: Give some name to your configuration, and if you dont require an empty config file I would suggest you to copy the settings from the existing “Release” transform.
enter image description here

Step 4: Right click on the web.config file and select the “Add Config Transform” option.
enter image description here

Step 5: And you should see your Staging config created. You can similarly create a qa and production/live configs too.
enter image description here

How To Use Entity Framework With MySql Database ?

Step 1 : Download and Install

First, you will need to download and install the following

Step 2 : Create A Database To Connect To

Make sure you create a database and a table with few columns for testing the connectivity using EF. In my example I have a ‘UserProfile’ table which has fields like userId, email, firstName, lastName etc.

Step 3 : Add Reference To Your Project

Add MySql.Data.dll and MySql.Data.Entity.dll to your project. enter image description here

Step 4 : Add ADO.NET Data Entity Model

enter image description here

enter image description here

enter image description here

enter image description here

enter image description here

enter image description here

Step 5 : Time To Test

public User CreateUser(User model)
{
    using (var context = new TestMySqlDbEntities())
    {
        // add user
        var createdUser = context.Users.Add(model);
        context.SaveChanges();
    }

    return model;
}

Ng Table with ASP.NET MVC WEB API and Angular js

Before reading this post, I recommend you to visit the ng-table official documentation and site and get the basic ng-table working.

Below is my api which accepts some grid params like

  • PageNumber
  • PageSize
  • SortColumn
  • SortOrder
  • SearchTerm

for simplicity I have not involved database in this example. This api method return a CustomerGridResult object, which has two properties first – Count i.e the count of the total records present and Data – the data to be returned after applying the above filters.

WEB API

// POST api/testapi
public CustomerGridResult Post(GridParams gridParam)
{
    var col = typeof(Customer).GetProperty(gridParam.SortColumn);
    var c = new List<Customer>();

    Customers =
        Customers.Where(
            m =>
            m.DisplayName.ToLower().Contains(gridParam.SearchTerm.ToLower())
        ).ToList();

    if(gridParam.SortOrder == "asc")
    {
        c = Customers
         .OrderBy(x => col.GetValue(x, null))
         .Skip((gridParam.PageNumber - 1) * gridParam.PageSize)
         .Take(gridParam.PageSize).ToList();
    }
    else
    {
        c = Customers
         .OrderByDescending(x => col.GetValue(x, null))
         .Skip((gridParam.PageNumber - 1) * gridParam.PageSize)
         .Take(gridParam.PageSize).ToList();    
    }

    return new CustomerGridResult
               {
                   Count = Customers.Count(),
                   Data = c
               };
}

HTML

<div data-ng-app="main" data-ng-controller="GridController">
     <table data-ng-table="tableParams">
        <tr data-ng-repeat="user in $data">
            <td data-title="'First Name'" data-sortable="'FirstName'">
                {{user.FirstName}}
            </td>
            <td data-title="'Last Name'" data-sortable="'LastName'">
                {{user.LastName}}
            </td>
            <td data-title="'Team'" data-sortable="'Company'">
                {{user.Company}}
            </td>
            <td data-title="'Pay'" data-sortable="'Salary'" class="currency">
                ${{user.Salary}}
            </td>
            <td data-title="'DOB'" data-sortable="'DateOfBirth'">
                {{user.DateOfBirth | date:'dd MMM yyyy'}}
            </td>
        </tr>
    </table>
</div>

AngularJs

var app = angular.module('main', ['ngTable', 'ngResource', 'ui.bootstrap']);

app.factory('customer', ['$http', function ($http) {
    return {
        getCustomers: function ($params) {
            return $http({
                headers: { 'Content-Type': 'application/json' },
                url: '/api/TestApi/',
                method: "POST",
                data: $params
            });
        }
        , getPlayersNames: function (searchTerm) {
            return $http.get('/api/testapi', { params: { searchTerm: searchTerm } });
        }
    };
} ]);

app.controller('GridController', ['$scope', '$http', 'ngTableParams', 'customer', function ($scope, $http, ngTableParams, customer) {

    // set defaults
    $scope.total = 5;
    $scope.page = 1;
    $scope.pageSize = 10;
    $scope.SortColumn = "FirstName";
    $scope.SortOrder = "asc";
    $scope.SearchTerm = "";

    $scope.tableParams = new ngTableParams(
        {
            page: $scope.page,
            count: $scope.total
        },
        {
            total: $scope.total, // length of data
            getData: function ($defer, params) {

                for (var i in params.sorting()) {
                    $scope.SortColumn = i;
                    $scope.SortOrder = params.sorting()[i];
                }

                var paramToPost = {
                    PageNumber: $scope.tableParams.page(),
                    PageSize: $scope.tableParams.count(),
                    SortColumn: $scope.SortColumn,
                    SortOrder: $scope.SortOrder,
                    SearchTerm: $scope.SearchTerm
                };

                customer.getCustomers(paramToPost)
                        .success(function (gridData) {
                            $defer.resolve(gridData.Data);
                            params.total(gridData.Count);
                        })
                        .error(function () {
                            alert("oops! something went wrong.");
                        });
            }
        }
    );
    // end of tableParams

    $scope.searchSubmit = function (val) {
        $scope.SearchTerm = val;
        $scope.tableParams.page(1);
        $scope.tableParams.reload();
    };

    $scope.clearSearch = function() {
        $scope.asyncSelected = "";
        $scope.searchSubmit("");
    };

    $scope.getLocation = function (val) {
        return customer.getPlayersNames(val)
            .then(function (res) {
                var players = [];
                angular.forEach(res.data, function (item) {
                    players.push(item.FirstName + ' ' + item.LastName);
                });
                console.log(players);
                return players;
            });
    };

} ]);

How to use angular ng attributes with TextBoxFor, EditorFor in Razor and ASP.NET MVC

New to angular.js today I tried to add ng-model data attribute to my textbox on my login form. The login form uses Html.TextboxFor helper. I tried the following but visual studio showed me an error

@Html.TextBoxFor(m => m.UserName, new { ng-model="user.name" })

in C# - is not valid.

So here’s a workaround for the same. Use _ (underscore) and Razor will convert the underscore to dash automatically.

This is what worked for me.

@Html.TextBoxFor(m => m.UserName, new { ng_model="user.name" })

Hope this helps. Had posted a question on stackoverflow too – Using angular attributes with TextBoxFor in ASP.NET MVC

HTTP Error 500.50 – URL Rewrite Module Error. The server variable is not allowed to be set.

I recently got this error when updating my rewrite rules in my system.webServer node of my web.config. The error message stated “HTTP Error 500.50 – URL Rewrite Module Error. The server variable “SERVER_PORT” is not allowed to be set. Add the server variable name to the allowed server variable list.”

Here is how you add a server variable using IIS

STEP 1 :

In your IIS with your website selected, select URL Rewrite option step1

STEP 2

Next select the View Server Variable option step2

STEP 3

Add server variable as shown below step3

Alternately you could also add through your web.config like below under <system.webServer></system.webServer> node.

<allowedServerVariables xdt:Transform="Insert">
    <add name="SERVER_PORT" />
    <add name="REMOTE_ADDR" />
</allowedServerVariables>

Writing your 1st HttpModule in ASP.NET under 2 minutes

What is a HttpModule ?

An HTTP module is an assembly that is called on every request made to your application. HTTP modules are called as part of the ASP.NET request pipeline and have access to life cycle events throughout the request. HTTP modules therefore give you the opportunity to examine incoming requests and take action based on the request. They also give you the opportunity to examine the outbound response and modify it.

ASP.NET HTTP modules are similar to ISAPI filters in that they run for all requests. However, they are written in managed code and are fully integrated with the life cycle of an ASP.NET application.

Typical uses for HTTP modules include:

  • Security
  • Statistics and logging
  • Custom headers or footers

In simpler words, An HTTP Module lets you add code that will be run every time a page is requested, so it’s a great solution for adding custom security checks.

Creating an HTTP Module

public class IsLocalHostHttpModule:IHttpModule
{
    public void Init(HttpApplication context)
    {
        context.BeginRequest += new EventHandler(HandleBeginRequest);
    }

    public void HandleBeginRequest(object source, EventArgs e)
    {
        HttpContext context = ((HttpApplication)source).Context;
        string ipAddress = context.Request.UserHostAddress;
        if (ipAddress != "::1" || ipAddress != "127.0.0.1")
        {
            context.Response.StatusCode = 403;
        }
    }

    public void Dispose() {}
}

Registering an HTTP Module

<configuration>
    <system.web>
        <httpModules>
            <add 
                 name="IsLocalHostHttpModule" 
                 type="Project.Folder.IsLocalHostHttpModule"
            />
            <!-- full qualified name should be mentioned in type -->
        </httpModules>
    </system.web>
</configuration>

References

Implementing reCAPTCHA in your ASP.NET MVC Project

What is reCAPTCHA ?

A reCAPTCHA is a program that protects websites against bots by generating and grading tests that humans can pass but current computer programs cannot. For example, humans can read distorted text as the one shown below, but current computer programs can’t. Know more…

img intro

Step 1 – Create a Recaptcha Key

The first thing you need to do is retrieve your public and private keys from reCAPTCHA, these can easily be retrieved by signing up here.

On signup, you will be asked to enter a domain where you intend to use reCAPTCHA, fill in your domain name and press the ‘Create Key’ button.

Note: By default, all keys work on “localhost” (or “127.0.0.1”) so you can always develop and test on your local machine.

img signup

Once done with this,you will get your public key and private key for your registered application. Keep it safe with you for now, we will be need them later.

Step 2 – Install Recaptcha for .NET

Now go to your ASP.NET MVC application and open your NuGet Package Manager by right clicking on your project and selecting the “Manage NuGet Packages…” option. Search for recaptcha for .NET and install it. Make sure you download the one shown in the screenshot below as there were plenty others with the same name.

img nuget install

As soon as the installation is complete, you will notice that a change is made to your web.config file, the following fields gets added to your <appSetting> section. Enter the public and private key you had got by registering your app at google.com/recaptcha‎.

<appSettings>

    <add key="recaptchaPublicKey" value="" />
    <add key="recaptchaPrivateKey" value="" />
</appSettings>

Step 3 – Add the Recaptcha Control to Your MVC View

Open your Views/Account/Register view and add this to the top of the page

@using Recaptcha.Web.Mvc

and include the recaptcha form using the following razor code

<li>
    @Html.Label("Recaptcha")
    @Html.Recaptcha()
</li>

Step 4 – Verify User’s Response to Recaptcha Challenge in your Controller/Action

Next step is to configure recaptcha in your controller/action, start with importing the following namespaces in your controller file (AccountController for this example)

using Recaptcha.Web;
using Recaptcha.Web.Mvc;

Next, go to your Register method and use the following code

RecaptchaVerificationHelper recaptchaHelper = this.GetRecaptchaVerificationHelper();

if (String.IsNullOrEmpty(recaptchaHelper.Response))
{
    ModelState.AddModelError("", "Captcha answer cannot be empty.");
    return View(model);
}

RecaptchaVerificationResult recaptchaResult = recaptchaHelper.VerifyRecaptchaResponse();

if (recaptchaResult != RecaptchaVerificationResult.Success)
{
    ModelState.AddModelError("", "Incorrect captcha answer.");
}

Ready To TEST ?

enter image description here

Run your application and go to your Register page and you now can see the recaptcha form on your register form.

Hope this helps. Any suggestions/feedback/queries if any are welcomed using the comments section below. Cheers!

References

Using Facebook Login with ASP.NET MVC 4

Login with Facebook is a very common feature that you will come across on the registration/login page on almost all good websites. ASP.NET MVC 4 includes support for OAuth and OpenID providers. Using these providers, you can let users log into your site using their existing credentials from Facebook, Twitter, Microsoft, and Google.

MVC 4 – Starter Template

This image shows the Login page from the Starter Site template, where a user can choose a Facebook, Twitter, Google or Microsoft icon to enable logging in with an external account:

img - starter template

However, In this blog post we will only be discussing about Facebook for Login.

Register your Website with Facebook

To authenticate users with their Facebook credentials, you must register your website with the Facebook. Head to developers.facebook.com and in the menu bar select App > Create a New App. You will be greeted with the below screen and a captcha. Once done you will be redirected to your App page.

img - create a new app

Your Facebook App Page

img - facebook app page Once you website’s Facebook App page is setup. Now you have you application’s App ID and App Secret keys. These values will be needed in your AuthConfig.cs file. If you open your AuthConfig.cs file you will find that the file contains code to register clients for external authentication providers. By default this code is commented out. For this tutorial, You must uncomment the code written for facebook, after uncommenting your AuthConfig.cs file should look like this.

public static class AuthConfig
{
    public static void RegisterAuth()
    {    
        //OAuthWebSecurity.RegisterMicrosoftClient(
        //    clientId: "",
        //    clientSecret: "");

        //OAuthWebSecurity.RegisterTwitterClient(
        //    consumerKey: "",
        //    consumerSecret: "");

        OAuthWebSecurity.RegisterFacebookClient(
            appId: "ENTER_KEY_FROM_YOUR_CREATED_FACEBOOK_APP_PAGE",
            appSecret: "ENTER_SECRET_KEY");

        //OAuthWebSecurity.RegisterGoogleClient();
    }
}

The appId and appSecret key values you will find in your Facebook App page.

First Test

Time to test a few things out now, run your application and go to the login page, Now you will the Facebook option under “Use another service to log in” header.

img - facebook first test

Click on that gives an error message, which says:

Given URL is not allowed by the Application configuration.: One or more of the given URLs is not allowed by the App’s settings. It must match the Website URL or Canvas URL, or the domain must be a subdomain of one of the App’s domains.

Now this is because we have not configured our Facebook App Page properly, go to your app page and in your settings. Add your localhost url along with the port number as shown below. Check out this stackoverflow thread for more info on this error.

img - facebook app settings change

Second Test

Now after making the above set of changes, lets again go to the login page and try logging in using Facebook, and voila !

enter image description here

In the above screenshot you can see the name I had specified while creating the app page “logintestbyyasser”. Press okay and continue. Now what happens when you click on the “Okay” button is interesting and is explained in the next section

ExternalLoginCallback

When the okay button is pressed control flows into ExternalLoginCallback action of the AccountController. The first line of this action says:

AuthenticationResult result = OAuthWebSecurity.VerifyAuthentication(Url.Action("ExternalLoginCallback", new { ReturnUrl = returnUrl }));

A lot of useful information can be retrieved from this result variable returned by the OAuthWebSecurity.VerifyAuthentication() method. Check the below screenshot of the debug values.

img - debug values

You could read values out from the result variable in the following manner. You should be able to access the basic user info like username, name, facebook link, gender and most important of all the accesstoken.

string username = result.UserName;

var id = result.ExtraData["id"];
var name = result.ExtraData["name"];
var link = result.ExtraData["link"];
var gender = result.ExtraData["gender"];
var accesstoken = result.ExtraData["accesstoken"];

Get user data from Facebook

You can get more user details by talking to facebook api using the facebook sdk. The easiest way is to download and install using the nuget download manager.

enter image description here

Once downloaded now you can use the following set of code to get user details using the userId fetched from the result variable.

var client = new FacebookClient();
dynamic me = client.Get(id);

The above line of code returns a json object as shown below, try this link – http://graph.facebook.com/790295720

{
    "id": "790295720",
    "first_name": "Yasser",
    "gender": "male",
    "last_name": "Shaikh",
    "link": "https://www.facebook.com/yrshaikh",
    "locale": "en_US",
    "middle_name": "Riaz",
    "name": "Yasser Riaz Shaikh",
    "username": "yrshaikh"
}

You can get a host of user details using the accesstoken as shown below :

var client = new FacebookClient(accesstoken);
dynamic me = client.Get("me");

In my example I was able to retrieve the below information for the logged in user (myprofile)

  • id
  • bio
  • education
  • favorite_athletes
  • favorite_teams
  • first_name
  • gender
  • hometown
  • last_name
  • link
  • location
  • locale
  • middle_name
  • name
  • sports
  • timezone
  • updated_time
  • username
  • verified
  • work

Get Email, More Permissions, Scope and other details

The above details we fetched were the basic details that you get, incase you want more details of the user like his email adress, pubish_stream or read_stream then it gets a little complicated. Thanks to Matheus Valiente Souza‘s answer to this stackoverflow thread, originally posted on this blog – Authenticating Facebook users with MVC 4 OAuth AND obtaining Scope Permissions!

You will need to create the following class – FacebookScopedClient, taken blindly from here – tested and it works!

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;
using DotNetOpenAuth.AspNet;
using Newtonsoft.Json;

namespace facebooklogintest.App_Start
{
    public class FacebookScopedClient : IAuthenticationClient
    {
        private string appId;
        private string appSecret;
        private string scope;

        private const string baseUrl = "https://www.facebook.com/dialog/oauth?client_id=";
        public const string graphApiToken = "https://graph.facebook.com/oauth/access_token?";
        public const string graphApiMe = "https://graph.facebook.com/me?";

        private static string GetHTML(string URL)
        {
            string connectionString = URL;

            try
            {
                System.Net.HttpWebRequest myRequest = (HttpWebRequest) WebRequest.Create(connectionString);
                myRequest.Credentials = CredentialCache.DefaultCredentials;
                //// Get the response
                WebResponse webResponse = myRequest.GetResponse();
                Stream respStream = webResponse.GetResponseStream();
                ////
                StreamReader ioStream = new StreamReader(respStream);
                string pageContent = ioStream.ReadToEnd();
                //// Close streams
                ioStream.Close();
                respStream.Close();
                return pageContent;
            }
            catch (Exception)
            {
            }
            return null;
        }

        private IDictionary<string, string> GetUserData(string accessCode, string redirectURI)
        {
            string token =
                GetHTML(graphApiToken + "client_id=" + appId + "&redirect_uri=" + HttpUtility.UrlEncode(redirectURI) +
                        "&client_secret=" + appSecret + "&code=" + accessCode);
            if (token == null || token == "")
            {
                return null;
            }
            string access_token = token.Substring(token.IndexOf("access_token="), token.IndexOf("&"));
            string data = GetHTML(graphApiMe + "fields=id,name,email,username,gender,link&" + access_token);

            // this dictionary must contains
            Dictionary<string, string> userData = JsonConvert.DeserializeObject<Dictionary<string, string>>(data);
            return userData;
        }

        public FacebookScopedClient(string appId, string appSecret, string scope)
        {
            this.appId = appId;
            this.appSecret = appSecret;
            this.scope = scope;
        }

        public string ProviderName
        {
            get { return "Facebook"; }
        }

        public void RequestAuthentication(System.Web.HttpContextBase context, Uri returnUrl)
        {
            string url = baseUrl + appId + "&redirect_uri=" + HttpUtility.UrlEncode(returnUrl.ToString()) + "&scope=" +
                         scope;
            context.Response.Redirect(url);
        }

        public AuthenticationResult VerifyAuthentication(System.Web.HttpContextBase context)
        {
            string code = context.Request.QueryString["code"];

            string rawUrl = context.Request.Url.OriginalString;
            //From this we need to remove code portion
            rawUrl = Regex.Replace(rawUrl, "&code=[^&]*", "");

            IDictionary<string, string> userData = GetUserData(code, rawUrl);

            if (userData == null)
                return new AuthenticationResult(false, ProviderName, null, null, null);

            string id = userData["id"];
            string username = userData["username"];
            userData.Remove("id");
            userData.Remove("username");

            AuthenticationResult result = new AuthenticationResult(true, ProviderName, id, username, userData);
            return result;
        }
    }
} 

and then use this newly created class in your AuthConfig.cs like as shown below:

var facebooksocialData = new Dictionary<string, object>();
facebooksocialData.Add("scope", "email, publish_stream, read_stream");

OAuthWebSecurity.RegisterClient(new FacebookScopedClient(
    appId: "1376784812605727",
    appSecret: "ce379ea552bf423b6f8434da14c85f65",
    scope:"email, user_likes, friends_likes, user_birthday"),
    "Facebook",
    null
);

Important Note: For re-authenticating your facebook account with the app with new set of permissions, you may need to remove the existing set of permission and trying again.

And now when you try logging in using Facebook the following screen is shown, but this time more permissions are requested this includes friend list, email address, birthday and likes and your friend’s likes.

enter image description here

Now if you check again with the following code

string email =  result.ExtraData["email"];

Hope this help, please give your feedback/suggestions/correction using the comment box below. Thanks.

References

Achieving versioning with Web API in ASP.NET MVC

There are two ways to achieve versioning with Web API

Method 1 : The simple method

/api/accountv1/
/api/accountv2/

The simplest way I found in versioning your API is to create an identical controller of “AccountV1Controller” and name it “AccountV2Controller“, notice the suffix V1 and V2 in controller name, we’ll depend on this part to select the appropriate controller based on API version.

Method 2 : Using routes

/api/v1/account
/api/v2/account

Or you could play with Routes to get the same behavior

config.Routes.MapHttpRoute(
    name: "1-0Api",
    routeTemplate: "api/v1/Account/{id}",
    defaults: new { controller = "AccountV1", id = RouteParameter.Optional }
);
config.Routes.MapHttpRoute(
    name: "2-0Api",
    routeTemplate: "api/v2/Account/{id}",
    defaults: new { controller = "AccountV2", id = RouteParameter.Optional }
);

Taken from here and here