European ASP.NET 4.5 Hosting BLOG

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

ASP.NET Core 1.0 Hosting - HostForLIFE.eu :: How To Make DropDown List with ASP.NET Core WEB API and AngularJS 2 ?

clock May 22, 2016 05:48 by author Anthony

In this post, we take it to next level and implement it with ASP.NET Core Web API and AngularJS 2. But starting/configuring AngularJS 2 with ASP.NET Core is not straight forward and it requires some manual configurations to be done. If you are not sure how to do it, I recommend you to read this helpful post to find out post how to start with AngularJS 2 in ASP.NET Core with TypeScript using Visual Studio 2015.

Cascading DropDown List with ASP.NET Core WEB API and AngularJS 2

I believe now you have an idea about starting with AngularJS 2. I also followed same steps to configure this demo project as mentioned. So now let’s move to next part. Please note, I selected the “Web application template” while creating the project but removed all the unnecessary code.

Add Models classes in Models folder

First, add Country and State model classes in Models folder. Following is the code for Country.cs. This class has 2 properties and a method which returns a list of countries. For demo, I used static data but you can also get the same list from database.

public class Country
{
    public int id { get; set; }
    public string name { get; set; }

    public Country(int CountryID, string CountryName)
    {
        id = CountryID;
        name = CountryName;
    }

    public static List<Country> GetAllCountries()
    {
        List<Country> lstCountries = new List<Country>();
        lstCountries.Add(new Country(1, "USA"));
        lstCountries.Add(new Country(2, "India"));
        lstCountries.Add(new Country(3, "Australia"));
        lstCountries.Add(new Country(4, "Canada"));
        return lstCountries ;
    }
}

And following is the code for State.cs. This class has 3 properties and a method which returns a list of states. Nothing fancy, self-explanatory code.

public class State
{
    public int id { get; set; }
    public int countryid { get; set; }
    public string name { get; set; }

    public State(int StateID, int CountryID, string StateName)
    {
        id = StateID;
        countryid = CountryID;
        name = StateName;
    }
    public static List<State> GetAllStates()
    {
        List<State>  lstState = new List<State>();
        lstState.Add(new State(1, 1, "Arizona"));
        lstState.Add(new State(2, 1, "Alaska"));
        lstState.Add(new State(3, 1, "Florida"));
        lstState.Add(new State(4, 1, "Hawaii"));
        lstState.Add(new State(5, 2, "Gujarat"));
        lstState.Add(new State(6, 2, "Goa"));
        lstState.Add(new State(7, 2, "Punjab"));
        lstState.Add(new State(8, 3, "Queensland"));
        lstState.Add(new State(9, 3, "South Australia"));
        lstState.Add(new State(10, 3, "Tasmania"));
        lstState.Add(new State(11, 4, "Alberta"));
        lstState.Add(new State(12, 4, "Ontario"));
        lstState.Add(new State(13, 4, "Quebec"));
        lstState.Add(new State(14, 4, "Saskatchewan"));
        return lstState;
    }
}


Add action methods in controller
Next step is to make our WEB API ready. For your information, ASP.NET Core comes with Unified Programming Model for MVC and Web API. So open HomeController.cs and add following 2 action methods.

[HttpGet]
[Route("api/Home/GetCountries")]
public IEnumerable<Country> GetCountries()
{
    return Country.GetAllCountries();
}

[HttpGet]
[Route("api/Home/GetState/{countryid?}")]
public IEnumerable<State> GetState(int countryid = 1)
{
    List<State> lstState = State.GetAllStates();
    return lstState.Where(item => item.countryid == countryid);
}
GetCountries() method makes call to Country.GetAllCountries(); and returns the list. Where the second method GetState() accepts countryid as parameters and based on the its value, filters the state list and return the same.

Note countryid parameter is optional for GetState() action method. And also a default value is supplied to it. Why? Well, this actually allows you to pass countryid in querystring. And while calling REST APIs via AngularJS, the arguments/parameters are appended to URL as part of querystring. And that’s why we must allow our API to support querystring. So following URL,

http://localhost:53483/api/Home/GetState/1
is similar to
http://localhost:53483/api/Home/GetState?countryid=1

AngularJS 2 application structure
Create a folder named “app” in wwwroot folder. If you have already created while configuring AngularJS 2 then ignore this step. Now within this folder, following files needs to added.

I already explained about this application structure and about code here. But let me just summarize here again.

country.ts: This file has a simple class called Country with 2 properties id and name.
state.ts: This file has a simple class called States with 3 properties id, countryid and name.
countrylistcomponent.ts: This file contains code for defining a component and template used to render HTML. The Component adds the metadata to the class. And it also makes call to Angular 2 Service, which in turn calls WEB API.
CountryTemplate.html: This file has HTML code to render select dropdown list.
dataservice.ts: This is an Angular 2 service which makes WEB API calls to get list of countries and states.
main.ts: This file contains code to bootstrap angularjs 2 in our application.
country.cs

export class Country {
    constructor(public id: number, public name: string) { }
}
state.cs

export class State {
    constructor(public id: number,
                public countryid: number,
                public name: string) { }
}
dataservice.ts

import { Injectable } from 'angular2/core';
import {Http, URLSearchParams} from "angular2/http";
import 'rxjs/Rx';
import { Country } from './country';
import { State } from './state';


@Injectable()
export class DataService {
    constructor(public http: Http) {
        this.http = http;
    }
    getCountries() {
        return this.http.get("/api/Home/GetCountries")
            .map((responseData) => responseData.json());
    }

    getStates(countryid: string) {
        var params = new URLSearchParams();
        params.set('countryid', countryid);
        return this.http.get("/api/Home/GetState", { search: params })
            .map((responseData) => responseData.json());
    }
}

As you know AngularJS 2 is modular. And as here in this service, we need to make use of HTTP service. So we need to import it. Similarly URLSearchParams, which is used to pass arguments to WEB API method. Therefore,
import {Http, URLSearchParams} from "angular2/http";

And the other import statement import 'rxjs/Rx';, imports ReactiveX library. The Http service in Angular 1 returns a promise where Angular 2 returns an Observable object. And The Observable classes in Angular 2 are provided by the ReactiveX library.

Here, first we inject $http service in class constructor. And we use http.get() to run our HTTP request. And this returns an Observable object. Since it’s an observable object, we can use map() to convert the response into JSON response.

countrylistcomponent.ts

import { Component } from 'angular2/core';
import { DataService } from './dataservice';
import { Country } from './country';
import { State } from './state';

@Component({
    selector: 'my-country-list',
    templateUrl: 'app/CountryTemplate.html',
    providers: [DataService]
})
export class CountryListComponent {
    selectedCountry: Country = new Country(0, 'India');
    countries: Country[];
    states: State[];

    constructor(private _dataService: DataService) {
        this._dataService.getCountries().subscribe(data => { this.countries = data });
    }

    onSelect(countryid) {
        if (countryid == 0)
            this.states = null;
        else
            this._dataService.getStates(countryid).subscribe(data => { this.states = data });
    }
}
This file is modified to use the service to get countries and states list.

First, import the Service and then within @Component directive, set providers: [DataService].
And inject the service in CountryListComponent constructor. And in constructor, call getCountries() method to get list of countries from the service. Since the service returns Observable object, we can use .subscribe() method to get the output in variable.
Also defined onSelect method which will be called onChange event of country dropdown list. This method calls service to get the list of states based on selected countryid and then using subscribe get the list in states variable.
main.ts

import { bootstrap } from 'angular2/platform/browser';
import {HTTP_PROVIDERS} from "angular2/http";
import { CountryListComponent } from './countrylistcomponent';

bootstrap(CountryListComponent, [HTTP_PROVIDERS]);
This file has code to bootstrap AngularJS 2 in our application. Along with that, it also bootstrap application root/parent component. Angular’s http module exposes HTTP_PROVIDERS, which has all the providers that we need, to code http action in our service. Therefore add the http providers to the bootstrap, by importing the HTTP_PROVIDERS from angular2/http.

CountryTemplate.html

<div class="row">
    <div class="col-md-5" style="text-align:right;">
        <label>Country:</label>
    </div>
    <div class="col-md-7" style="text-align:left;">
        <select [(ngModel)]="selectedCountry.id" (change)="onSelect($event.target.value)" style="width:150px;">
            <option value="0">--Select--</option>
            <option *ngFor="let country of countries" value={{country.id}}>{{country.name}}</option>
        </select>
    </div>
</div>
<br />
<div class="row">
    <div class="col-md-5" style="text-align:right;">
        <label>State:</label>
    </div>
    <div class="col-md-7" style="text-align:left;">
        <select style="width:150px;">
            <option value="0">--Select--</option>
            <option *ngFor="let state of states " value={{state.id}}>{{state.name}}</option>
        </select>
    </div>
</div>
And finally the HTML template. This file name is used while specifying metadata for CountryListComponent class.
There are 2 dropdowns list one for country and other for state and also change event defined on country dropdown list. Angular 2 has different way of defining event. Take the HTML event and wrap it with parentheses. $event.target.value will give the selected country id.

I also want to bring in your attention a change made in AngularJS 2 version “2.0.0-beta.17” with respect to *ngFor. Previously we were using,

*ngFor="#state of states"
but in this version, it is changed a bit. Instead of “#”, use “let”

*ngFor="let state of states"
And finally since we are using Angular 2 Http service in our application, we need to include the script in the layout. So, open the _Layout.cshtml file located at Views/Shared/ and add the following code right after the script element that loads Angular 2 core.

<environment names="Development">
  <script src="~/lib/npmlibs/angular2/http.dev.js"></script>
</environment>
<environment names="Staging,Production">
  <script src="~/lib/npmlibs/angular2/http.min.js"></script>
</environment>
Wait!!! We still need to show what we have done till now on UI. So open Views/Home/Index.cshtml and add angular component tag <my-country-list></my-country-list> to HTML file. And we also need to load the application and all its modules. So place following script section to the end of the file.

@section Scripts {
    <script>
        System.config({
            packages: {
                'app': { defaultExtension: 'js' },
                'lib': { defaultExtension: 'js' },
            },
        });

        System.import('app/main')
            .then(null, console.error.bind(console));
    </script>
}

 

 

HostForLIFE.eu ASP.NET Core 1.0 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.

 



ASP.NET Core 1.0 Hosting - HostForLIFE.eu :: How To Inject Codes in HTTP Pipeline?

clock May 12, 2016 21:49 by author Anthony

In this tutorial, I will explain about how to inject little codes in HTTP Pipeline in ASP.NET Core. “Middleware is defined in the OWIN specification as pass through components that form a pipeline between a server and application to inspect, route, or modify request and response messages for a specific purpose. Middleware consists of application components are incorporated into the ASP.NET HTTP pipeline.” The text is in the ASP.NET Core documentation, and as can be seen, with middleware we can insert a component that is incorporated in ASP.NET HTTP pipeline, that is, we can develop a code with a purpose to manipulate the requests and responses.

A characteristic of middleware is that normally there will a chain of middleware whereby order of configuration, one is called after the end of other and the current middleware can on any moment cancel invoking the next middleware, thus all chains of middleware will be canceled.

middlwares

Do you have doubts about what is middlewares? We can compare middleware with the old http modules that today don’t exist in the new ASP.NET. I have already seen somebody comparing middlewares with a hamburger, because the middle is middleware and the ends are the application and the server. How much more middleware, bigger is the hamburger.

To get more clarity about the subject, I am going to show some middlewares that already are utilized by default in application templates to ASP.NET Core, and after I am going to create a custom middleware.

Below I show the startup class, note that there are some comments that indicate where there is a middleware.

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
        {
            loggerFactory.AddConsole(Configuration.GetSection("Logging"));
            loggerFactory.AddDebug();

            app.UseApplicationInsightsRequestTelemetry();

            if (env.IsDevelopment())
            {
                app.UseBrowserLink(); //Middleware
                app.UseDeveloperExceptionPage(); //Middleware
                app.UseDatabaseErrorPage(); //Middleware
            }
            else
            {
                app.UseExceptionHandler("/Home/Error"); //Middleware

                try
                {
                    using (var serviceScope = app.ApplicationServices.GetRequiredService<IServiceScopeFactory>()
                        .CreateScope())
                    {
                        serviceScope.ServiceProvider.GetService<ApplicationDbContext>()
                             .Database.Migrate();
                    }
                }
                catch { }
            }

            app.UseIISPlatformHandler(options => options.AuthenticationDescriptions.Clear()); //Middleware

            app.UseApplicationInsightsExceptionTelemetry(); //Middleware

            app.UseStaticFiles(); //Middleware

            app.UseIdentity(); //Middleware

            app.UseMvc(routes =>
            {
                routes.MapRoute(
                    name: "default",
                    template: "{controller=Home}/{action=Index}/{id?}");
            }); //Middleware
        }

Did you see the middlewares utilized in code? Here, each middleware has a responsibility and the gain that we have is we can choose only the ones needed for our project, different from old version of ASP.NET that by default many features were added even when they were not necessary. A very good phrase says: “Pay only by what you use”, in other words, how many fewer middleware you use, the less heavy will be the HTPP pipeline.

Other thing to observe that in code above, all the middlewares start with a “Use”, this is a pattern done by team ASP.NET.

Now I am going to create a own middleware and my goal will be creating one that shows the total time of application to take care of a request. Below following the code.

using Microsoft.AspNet.Builder;
using Microsoft.AspNet.Http;
using System.Diagnostics;
using System.IO;
using System.Threading.Tasks;

namespace MiddlewareArticle.Middleware
{
    public class ResponseTime
    {
        RequestDelegate _next;

        public ResponseTime(RequestDelegate next)
        {
            _next = next;
        }

        public async Task Invoke(HttpContext context)
        {
            var sw = new Stopwatch();
            sw.Start();

            await _next(context);

            var isHtml = context.Response.ContentType?.ToLower().Contains("text/html");

            if (context.Response.StatusCode == 200 && isHtml.GetValueOrDefault())
            {
                var body = context.Response.Body;
               
                using (var streamWriter = new StreamWriter(body))
                {
                    var textHtml = string.Format(
                        "<footer><div id='process'>Response Time {0} milliseconds.</div>",
                        sw.ElapsedMilliseconds);
                    streamWriter.Write(textHtml);
                }
            }
        }
    }
}


As can be seen, making a middleware is not difficult, it needs a constructor to receive the next middleware and an “Invoke” method that receives the context of HTTP. The goal of showing the total time of application gets in method Invoke. Before calling the next middleware, it is started the time and after of calling the next middleware, when all the middlewares already were executed, I execute the code to show in the HTML the total time.

Remember, I know that all middleware were executed because our middleware must be configured before of all others, thus the code will wait all executions and after the instruction “await _next(context);” we can write our code.

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
        {
            app.UseMiddleware<ResponseTime>(); //Our Middleware
           
            loggerFactory.AddConsole(Configuration.GetSection("Logging"));
            loggerFactory.AddDebug();
           
            //...
            //Continue with others codes

The code above is only to show the set up of our middleware in the Configure method of the Startup class. To that this works, it is needed using the instruction “app.UseMiddleware();”, where the UseMiddleware method is used to call custom middlewares.

Conclusion


The ASP.NET Core has changed, not the code that we know, but your core and by this, the way of manipulating a request and a response was changed to middleware. Now it’s lighter and easier to stay between an application and a server. However, take care, it is not because it got better that you must now only use that to develop.

 

 

HostForLIFE.eu ASP.NET Core 1.0 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 2016 Hosting, ASP.NET Core 2.2.1 Hosting, ASP.NET MVC 6 Hosting and SQL 2017 Hosting.


Tag cloud

Sign in