Aug 5, 2014

Posted in , , ,

ASP.NET MVC 5.2 Hosting - HostForLIFE.eu :: How to Combine Angular with ASP.NET MVC 5.2

Angular is a great tool, but it took some time to find a way to combine it with ASP.NET MVC 5.2. This is basically how I did it. First, create a new ASP.NET MVC 5.2 application. Next, install the Angular package via NuGet.

The objective is to use the normal ASP.NET MVC 5.2 navigation, unless for certain URLs, when we'll let Angular take over. So http://www.example.com/Account/Login would be handled by ASP.NET ("ASP.NET-mode"), but http://www.example.com/#/Customers would be handled by Angular ("Angular-mode"). Of course, it's ASP.NET serving us the Customers page, but after that, we want to use Angular for data-binding, navigation, routing, the forms, etc.

Then, Add a new Controller with one method, Index(), that returns View(). Standard ASP.NET up until now. I named mine AngularController. Next, add a View in the corresponding folder (in my case: /Angular/Index.cshtml). In this view, set up your main Angular view. Something like:
@{
ViewBag.Title = "Index";
}
<div ng-app="app">
<div ng-controller="main as vm">
<div ng-view class="shuffle-animation"></div>
</div>
</div>
@section scripts {
@Scripts.Render("~/bundles/angular")
}


So when we're in "Angular-mode", we want ASP.NET MVC 5.2 to include our Angular scripts. The angular bundle looks something like this (in /App_Start/BundleConfig.cs):
undles.Add(new Bundle("~/bundles/angular").Include(

"~/Scripts/angular.js",
"~/Scripts/angular-animate.js",
"~/Scripts/angular-route.js",
"~/Scripts/angular-sanitize.js",
"~/Scripts/app/app.js",
"~/Scripts/app/config.js",
"~/Scripts/app/main.js",
"~/Scripts/app/customers/customers.js"));


The reason I'm not using a ScriptBundle is because we don't want ASP.NET 4.5.2 to minify the Angular scripts. This causes errors because Angular sometimes depends on function arguments to be specific strings.  For now, minification isn't important, but in a production-environment, you would want to use the minified Angular scripts.

In app.js, config.js and main.js, I have put the necessary code to get Angular running. The most important part is the getRoutes function in config.js:

function getRoutes() {
return [
{
url: '/customers',
templateUrl: '/Scripts/app/customers/customers.html'
}
];
}


Finally, the customers.html and customers.js contain my Angular logic and HTML markup for this specific page. This now allows you to navigate to http://localhost:1748/Angular/#/ (your portnumber may vary of course).

There you have it. ASP.NET MVC 5.2 is serving the HTML page that includes references to Angular scripts and templates, the browser downloads all that, and then Angular wires it all together!

Adding this to your navigation is as simple as adding this tag to your _Layout.cshtml file:
<li><a href="https://www.blogger.com/Angular/#/customers">Customers</a></li>

Don't forget the hash.  Now lets add a second page. This will make the difference between what I've been calling "ASP.NET-mode" and "Angular-mode" more clear.

Add a new html file and a new javascript file to the /Scripts/app/customers/ folder, add the route to config.js and add the javascript file to the Angular bundle in BundleConfig.cs. The link in my case would now be:
<a href="https://www.blogger.com/Angular/#/customers/create">Create new customer</a>

Now, when you run the app, navigating from /Angular/#/customers to, say, /Account/Login will load the entire new page. But navigating from /Angular/#/customers to /Anguler/#/customers/create stays within Angular, and just loads the new template, "staying inside" your SPA. You can sort of notice it because loading a new page "inside" the SPA feels faster. So we've effectively combined classic ASP.NET MVC with Angular, allowing us to choose where we want/need which.

May 21, 2014

Posted in , , , ,

Free ASP.NET MVC 5.1.2 Cloud Hosting - HostForLIFE.eu - How to set an initial selected value in a RadioButtonList on ASP.NET MVC?

I have discussed about how to generate a RadioButtonList in ASP.Net MVC. If you didn’t read that, please read before proceeding this article because this is an absolute continuation of that article. Here is the link ASP.NET MVC - Generate RadioButtonList. In this article we will go over setting an initial selected value in RadioButtonList in ASP.NET MVC.
http://www.hostforlife.eu/European-ASPNET-Hosting-Free-Trial
Let’s understand this with an example. We will be using same example which we have used in the previous article. To set an initial selected value in a RadioButtonList, we can make use of IsSelected bit column in tblDepartment table. Follow below steps to get the intended output.

Step 1: Add IsSelected bit column to tblDepartment table.
ALTER TABLE tblDepartment
ADD IsSelected BIT
Step 2: Initially this column will be null for all the rows in tblDepartment table. If we want IT department to be selected by default, set IsSelected=1 for IT department row.
Update tblDepartment Set IsSelected = 1 Where Id = 1

Step 3: Refresh ADO.NET Entity Data Model.
Step 4: Finally, make the following changes to the Index View.

@model MVCDemo.Models.Company
@{
ViewBag.Title = “Index”;
}
<h2>Index</h2>
@foreach (var department in Model.Departments)
{
@Html.RadioButtonFor(m => m.SelectedDepartment, department.Id)
,(department.IsSelected.HasValue && department.IsSelected.Value)?new{@checked=”checked“}:null)@department.Name
}
Notice that @Html.RadioButtonFor helper has one more parameter to determine the initial selected value.  Run the application and we will get the output as below.
Now, if you want HR department to be selected instead of IT, set IsSelected=1 for HR department and IsSelected=0 for IT department.
Update tblDepartment Set IsSelected = 1 Where Id = 2
Update tblDepartment Set IsSelected = 0 Where Id = 1

May 6, 2014

Posted in , , , ,

Free ASP.NET MVC 5 Hosting - HostForLIFE.eu :: Using Flags Enumeration With ASP.NET MVC & CodeFluent Entities

Enumeration support
CodeFluent Entities provides full support of “enumeration” types and multi value enumerations (flag enumeration) in ASP.NET MVC Hosting.
To declare a multi value enumeration, go to the enumeration type properties and set the, go to the enumeration type properties and set the Multi Value property to True.
And since the build version (646) you can set an enumeration value as the combination of other values (by their name).

Using enumeration values with ASP.NET MVC
Let’s use these concepts on an ASP.NET MVC application, I will use the model above as an example. I also have a MediaController with an Index action to list all Medias and an Edit action (Get and Post).

The default template for an enumeration value is a textbox, so if I write something like this:

@Html.EditorFor(m => m.MediaType)

I will get a textbox for my enumeration value.
This will work but the user will have to write a correct enumeration value, and unless each user knows all the possible enumeration values, this is not an acceptable solution.

It would be better to display a dropdown list instead. Let’s create a template named Choice.cshtml on the Views\Shared\EditorTemplates folder.

@model Enum
@{
var items = from object value in Enum.GetValues(Model.GetType())
select new { Value = value, Text = value.ToString() };
SelectList list = new SelectList(items, "Value", "Text", Model);
}
@Html.DropDownList("", list)
And now if we choose this as the template for our enumeration:
@Html.EditorFor(m => m.MediaType, "Choice")
 
 
This works fine and we can use the Choice.cshtml template for any enumeration type.  

Using multi enumeration values with ASP.NET MVC
Let’s now do the same work for a multi value enumeration (flag enumeration). First we create a template named MultiChoice.cshtml on the Views\Shared\EditorTemplates folder.
@model Enum
@{
var items = from object value in Enum.GetValues(Model.GetType())
select new { Value = value, Text = value.ToString() };
IEnumerable selected = CodeFluent.Runtime.Utilities.ConvertUtilities.SplitEnumValues(Model);
MultiSelectList list = new MultiSelectList(items, "Value", "Text", selected);
}
@Html.DropDownList("", list, new { multiple = "multiple" })
We use here a method on the CodeFluent.Runtime.Utilities namespace to split a flag value into a list of enumeration values. Let’s try it for our multi value enumeration.
@Html.EditorFor(m => m.ReleaseFormat, "MultiChoice")
 
 This seems to work but it doesn’t, when I try to save my form, not all values are saved (from the flag multi value enumeration). This is because MVC does not bind correctly the multi value enumeration to my model.

We need to add a custom model binder (System.Web.Mvc.IModelBinder) and a value provider (System.Web.Mvc.IValueProvider). I will use some utilities classes that are used for the ASP.NET Web Site V2 producer, they can be found under the Templates folder in the CodeFluent Entities installation location (Program Files (x86)\SoftFluent\CodeFluent\Modeler\Templates\UI\AspNetMvc\Code\Utilities.cs.tpl). I will copy the content of the file in my ASP.NET MVC project filling the correct namespace. Don’t forget to add a reference to the CodeFluent.Runtime.Web assembly.


Finally, we register the EntityBinder and the EntityValueProviderFactory classes that we have just added. On the Application Start:

ValueProviderFactories.Factories.Add(new EntityValueProviderFactory());
ModelBinderProviders.BinderProviders.Add(new EntityBinder());

This time everything works great. This post was inspired by the CodeFluent Entities templates when wondering what the ASP.NET Web Site V2 producer generates

Mar 19, 2014

Posted in , , ,

FREE ASP.NET MVC 5 Germany Hosting - HostForLIFE.eu ASP.NET MVC 5 Authentication Breakdown

I've been inspecting the new bits of ASP.NET MVC 5 and trying to make sense of the new paradigm that me, as .NET developer, is going to be working in. This new shift will probably be known as the Open Web Inerface for .NET era or more succinctly the OWIN era. OWIN is a middleware implementation for .NET that will allow developers, like me, to hook into a deeper pipeline to perform tasks like logging, exception handling, authentication, and more that my imagination can't contemplate just yet. This post isn't about OWIN and the possibilities, but it is about the new authentication found in ASP.NET MVC 5.

http://hostforlife.eu/European-ASPNET-MVC-4-Hosting

Registering the Middleware

I started by creating a new ASP.NET MVC 5 project using the existing templates that come with Visual Studio 2013 and picked the individual user accounts option for authentication. This means my user information will be stored locally in a data storage. The default data storage is SQL Server. Looking in the App_Start folder, I find Startup.Auth.cs. The file contents looks like this:
    public partial class Startup
    {
        // For more information on configuring authentication, please visit http://go.microsoft.com/fwlink/?LinkId=301864
        public void ConfigureAuth(IAppBuilder app)
        {
            // Enable the application to use a cookie to store information for the signed in user
            app.UseCookieAuthentication(new CookieAuthenticationOptions
            {
                AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
                LoginPath = new PathString("/Account/Login")
            });
            // Use a cookie to temporarily store information about a user logging in with a third party login provider
            app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);

            // Uncomment the following lines to enable logging in with third party login providers
            //app.UseMicrosoftAccountAuthentication(
            //    clientId: "",
            //    clientSecret: "");

            //app.UseTwitterAuthentication(
            //   consumerKey: "",
            //   consumerSecret: "");

            //app.UseFacebookAuthentication(
            //   appId: "",
            //   appSecret: "");

            //app.UseGoogleAuthentication();
        }
    } 
I also found this in the web.config of the application.
<system.web>
    <authentication mode="None" />
    <compilation debug="true" targetFramework="4.5" />
    <httpRuntime targetFramework="4.5" />
  </system.web>
  <system.webServer>
    <modules>
      <remove name="FormsAuthenticationModule" />
    </modules>
  </system.webServer> 
 
With these two files, I realize that the old forms authentication model has been replaced by the OWIN pipeline. Diving deeper into the calls found in the startup app, I also realize that each of the calls just registers a new middleware class to handle that particular auth provider. This is the google registration.

http://www.hostforlife.eu/European-ASPNET-Hosting-Free-Trial
public static IAppBuilder UseGoogleAuthentication(this IAppBuilder app, GoogleAuthenticationOptions options)
    {
      if (app == null)
        throw new ArgumentNullException("app");
      if (options == null)
        throw new ArgumentNullException("options");
      app.Use((object) typeof (GoogleAuthenticationMiddleware), (object) app, (object) options);
      return app;
    }
nothing really fancy here, just instantiating the middle ware, then registering it with the application. The next step is to use the middleware.

AccountController

The AccountController is where ASP.NET MVC 5 gets confusing, because there is the noise introduced by the UserManager implementation. Ignore this, it is simply a Entity Framework implementation allowing you to save user information. I would most likely remove this, as I don't use Entity Framework myself.
The more interesting part of the AccountController is the IAuthenticationManager property.
private IAuthenticationManager AuthenticationManager
{
    get
    {
        return HttpContext.GetOwinContext().Authentication;
    }
} 
 
The IAuthenticationManager is being pulled from the OWIN implementation built on top of ASP.NET. When I start looking for uses of this property, I find the next generation of the things I've grown fond of with the FormsAuthentication class: SignIn and SignOut.
// Sign In
 AuthenticationManager.SignIn(new AuthenticationProperties() { IsPersistent = isPersistent }, identity);
// Sign Out
AuthenticationManager.SignOut(DefaultAuthenticationTypes.ExternalCookie);
The interesting part, is now I can create cookies with the distinction of whether they are internally generated, or generated by a third party provider: Twitter, Facebook, or Google.
The final piece of this is the ChallengeResult class, which looks to be optional to implement.
private class ChallengeResult : HttpUnauthorizedResult
{
    public ChallengeResult(string provider, string redirectUri) : this(provider, redirectUri, null)
    {
    }

    public ChallengeResult(string provider, string redirectUri, string userId)
    {
        LoginProvider = provider;
        RedirectUri = redirectUri;
        UserId = userId;
    }

    public string LoginProvider { get; set; }
    public string RedirectUri { get; set; }
    public string UserId { get; set; }

    public override void ExecuteResult(ControllerContext context)
    {
        var properties = new AuthenticationProperties() { RedirectUri = RedirectUri };
        if (UserId != null)
        {
            properties.Dictionary[XsrfKey] = UserId;
        }
        context.HttpContext.GetOwinContext().Authentication.Challenge(properties, LoginProvider);
    }
}
The only thing it does, is make a call to the IAuthenticationManager.Challenge to trigger the challenge built into the OWIN pipeline. This will redirect to a login page for the external auth providers.

Summary

All I need to get authentication working using OWIN is the following:
  • The contents of App_Start/Startup.Auth.cs.
  • The **IAuthenticationManager*.
  • Optionally, ChallengeResult, which is a nice helper Result.
How they work together:
  1. The authentication providers are registered with the app in startup.
  2. Cookies are handled by OWIN and the middleware.
  3. Each external auth provider's login challenge can be triggered using the ChallengeResult.
  4. Cookies are managed using IAuthenticationManager.SignIn and IAuthenticationManager.SignOut.
  5. Auth is based on Claims.
So after dissecting the start template, I found out what is basically important and what is just "helpful" stuff Microsoft gives me out of the box. There are definitely things that are still foggy to me, but I think I have a good understanding now of what it takes to do authentication in the OWIN era of ASP.NET MVC.