1

I have upgraded from MVC/AngularJS 1.x to DotNet Core 2.0/Angular 4.x. with @angular/common/http

Mostly it has been a breeze but the Web API is killing me. I got the get to work in a few minutes, but I have spent a week trying everything under the sun to get the Web Post to work.

What I have done here is really simple to replicate.

Go into Visual Studio 17 and clicked File/New Project

Choose Installed/Visual C#/.NET Core

Select the template: ASP.NET core Web Application

On the secondary screen set the dropdowns at the top to .NET Core and ASP.NET Core 2.0

Select the Red shield "A" Angular template

Let the project pull down the dependencies and rebuild.

EVERYTHING is the stock out of the box demo app from Microsoft except for:

Add the buttons to the screen.

Add code to the .ts to call the API Controller

Add the input parm to the get method in the controller

Add a very simple post method to the controller

I am also am trying to get DotNet Core 2.2/Angular 6.x. with @angular/httpclient to work with the exact same results. The get was very easy, but I have tried every configuration under the sun to get the post to work. I will make a post like this for the other version as well. Right now, I am just trying to get whatever I can to work and leave Angularjs 1.x behind.

import { Component, Inject } from '@angular/core';
import { Http, URLSearchParams, Headers } from '@angular/http';

@Component({
    selector: 'fetchdata',
    templateUrl: './fetchdata.component.html'
})
export class FetchDataComponent {
    public Http: Http;
    public BaseURL: string;
    public Headers: Headers;
    public startDateIndex = 0;
    public forecasts: WeatherForecast[] = [];
    public forecast: WeatherForecast = {
        dateFormatted: "3/27/2020",
        temperatureC: 0,
        temperatureF: 32,
        summary: "Cold Post"
    };

    constructor(http: Http, @Inject('BASE_URL') baseUrl: string) {
        this.Http = http;
        this.BaseURL = baseUrl;
        this.Headers = new Headers();
        this.Headers.append('Content-Type', 'application/json');
        http.get(baseUrl + 'api/SampleData/WeatherForecasts').subscribe(result => {
            this.forecasts = result.json() as WeatherForecast[];
        }, error => console.error(error));
    }
    public OnClick(pControl: string) {
        //console.log("LogOn.OnClick * pControl=" + pControl);
        switch (pControl) {
            case "Prior":
                this.startDateIndex -= 5;
                var params = new URLSearchParams;
                params.set("startDateIndex", this.startDateIndex.toString());
                this.Http.get(this.BaseURL + 'api/SampleData/WeatherForecasts/', { params: params }).subscribe(result => {
                    this.forecasts = result.json() as WeatherForecast[];
                }, error => console.error(error));
                break;
            case "Next":
                this.startDateIndex += 5;
                var params = new URLSearchParams;
                params.set("startDateIndex", this.startDateIndex.toString());
                this.Http.get(this.BaseURL + 'api/SampleData/WeatherForecasts/', { params: params }).subscribe(result => {
                    this.forecasts = result.json() as WeatherForecast[];
                }, error => console.error(error));
                break;
            case "Post":
                console.log("Post * this.forecast=" + JSON.stringify(this.forecast));
                var params = new URLSearchParams;
                params.set("weatherForecast", JSON.stringify(this.forecast));
                this.Http.post(this.BaseURL + '/api/SampleData/PostWeatherForecast/', this.forecast, { headers: this.Headers });
        }
    }
}

interface WeatherForecast {
    dateFormatted: string;
    temperatureC: number;
    temperatureF: number;
    summary: string;
}
<h1>Weather forecast</h1>

<p>This component demonstrates fetching data from the server.</p>

<p *ngIf="!forecasts"><em>Loading...</em></p>

<table class='table' *ngIf="forecasts">
    <thead>
        <tr>
            <th>Date</th>
            <th>Temp. (C)</th>
            <th>Temp. (F)</th>
            <th>Summary</th>
        </tr>
    </thead>
    <tbody>
        <tr *ngFor="let forecast of forecasts">
            <td>{{ forecast.dateFormatted }}</td>
            <td>{{ forecast.temperatureC }}</td>
            <td>{{ forecast.temperatureF }}</td>
            <td>{{ forecast.summary }}</td>
        </tr>
    </tbody>
</table>
<button class='btn btn-default pull-left' (click)="OnClick('Prior')">Previous</button>
<button class='btn btn-default pull-left' (click)="OnClick('Next')">Next</button>
<button class='btn btn-default pull-right' (click)="OnClick('Post')">Post</button>
    using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;

namespace NG_20.Controllers
{
    [Route("api/[controller]")]
    public class SampleDataController : Controller
    {
        private static string[] Summaries = new[]
        {
            "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
        };

        [HttpGet("[action]")]
        public IEnumerable<WeatherForecast> WeatherForecasts(int startDateIndex = 0)
        {
            var rng = new Random();
            return Enumerable.Range(1, 5).Select(index => new WeatherForecast
            {
                DateFormatted = DateTime.Now.AddDays(index + startDateIndex).ToString("d"),
                TemperatureC = rng.Next(-20, 55),
                Summary = Summaries[rng.Next(Summaries.Length)]
            });
        }

        [HttpPost("[action]")]
        public bool PostWeatherForecast([FromBody] WeatherForecast weatherForecast)
        {
            var forecast = weatherForecast;
            return true;
        }



        public class WeatherForecast
        {
            public string DateFormatted { get; set; }
            public int TemperatureC { get; set; }
            public string Summary { get; set; }

            public int TemperatureF
            {
                get
                {
                    return 32 + (int)(TemperatureC / 0.5556);
                }
            }
        }
    }
}
jimguyer
  • 161
  • 1
  • 8

2 Answers2

1

Solved! It will not make the API call without a subscriber.

import { Component, Inject } from '@angular/core';
import { Http, URLSearchParams, Headers } from '@angular/http';

@Component({
    selector: 'fetchdata',
    templateUrl: './fetchdata.component.html'
})
export class FetchDataComponent {
    public Http: Http;
    public BaseURL: string;
    public Headers: Headers;
    public startDateIndex = 0;
    public forecasts: WeatherForecast[] = [];
    public forecast: WeatherForecast = {
        dateFormatted: "3/27/2020",
        temperatureC: 0,
        temperatureF: 32,
        summary: "Cold Post"
    };

    constructor(http: Http, @Inject('BASE_URL') baseUrl: string) {
        this.Http = http;
        this.BaseURL = baseUrl;
        this.Headers = new Headers();
        this.Headers.append('Content-Type', 'application/json');
        http.get(baseUrl + 'api/SampleData/WeatherForecasts').subscribe(result => {
            this.forecasts = result.json() as WeatherForecast[];
        }, error => console.error(error));
    }
    public OnClick(pControl: string) {
        //console.log("LogOn.OnClick * pControl=" + pControl);
        switch (pControl) {
            case "Prior":
                this.startDateIndex -= 5;
                var params = new URLSearchParams;
                params.set("startDateIndex", this.startDateIndex.toString());
                this.Http.get(this.BaseURL + 'api/SampleData/WeatherForecasts/', { params: params })
                    .subscribe(result => { this.forecasts = result.json() as WeatherForecast[]; }, error => console.error(error));
                break;
            case "Next":
                this.startDateIndex += 5;
                var params = new URLSearchParams;
                params.set("startDateIndex", this.startDateIndex.toString());
                this.Http.get(this.BaseURL + 'api/SampleData/WeatherForecasts/', { params: params })
                    .subscribe(result => { this.forecasts = result.json() as WeatherForecast[]; }, error => console.error(error));
                break;
            case "Post":
                console.log("Post * this.forecast=" + JSON.stringify(this.forecast));
                this.Http.post(this.BaseURL + '/api/SampleData/PostWeatherForecast/', this.forecast, { headers: this.Headers })
                    .subscribe(result => { alert("Posted" + JSON.stringify(result.json())); }, error => console.error(error));
                break;
        }
    }
}

interface WeatherForecast {
    dateFormatted: string;
    temperatureC: number;
    temperatureF: number;
    summary: string;
}
    using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json.Linq;

namespace NG_20.Controllers
{
    [Route("api/[controller]/[action]")]
    public class SampleDataController : Controller
    {
        private static string[] Summaries = new[]
        {
            "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
        };

        [HttpGet]
        public IEnumerable<WeatherForecast> WeatherForecasts(int startDateIndex = 0)
        {
            var rng = new Random();
            return Enumerable.Range(1, 5).Select(index => new WeatherForecast
            {
                DateFormatted = DateTime.Now.AddDays(index + startDateIndex).ToString("d"),
                TemperatureC = rng.Next(-20, 55),
                Summary = Summaries[rng.Next(Summaries.Length)]
            });
        }

        [HttpPost]
        public object PostWeatherForecast([FromBody] object weatherForecast)
        {
            var forecast = JObject.Parse(weatherForecast.ToString()).ToObject<WeatherForecast>();
            var x = forecast.DateFormatted;
            return weatherForecast;
        }



        public class WeatherForecast
        {
            public string DateFormatted { get; set; }
            public int TemperatureC { get; set; }
            public string Summary { get; set; }

            public int TemperatureF
            {
                get
                {
                    return 32 + (int)(TemperatureC / 0.5556);
                }
            }
        }
    }
}
jimguyer
  • 161
  • 1
  • 8
1

Improved answer. The Interface is not necessary and other smaller refinements and removal of unnecessary code.

import { Component, Inject } from '@angular/core';
import { Http, URLSearchParams, Headers } from '@angular/http';

@Component({
    selector: 'fetchdata',
    templateUrl: './fetchdata.component.html'
})
export class FetchDataComponent {
    public Http: Http;
    public BaseURL: string;
    public Headers: Headers;
    public startDateIndex = 0;
    public forecasts = [];
    public forecast = { dateFormatted: "3/27/2020", temperatureC: 0, temperatureF: 32, summary: "Cold Post" };

    constructor(http: Http, @Inject('BASE_URL') baseUrl: string) {
        this.Http = http;
        this.BaseURL = baseUrl;
        this.Headers = new Headers();
        this.Headers.append('Content-Type', 'application/json');
        http.get(baseUrl + 'api/SampleData/WeatherForecasts')
            .subscribe(result => this.forecasts = result.json(), error => console.error(error));
    }
    public OnClick(pControl: string) {
        //console.log("LogOn.OnClick * pControl=" + pControl);
        switch (pControl) {
            case "Prior":
                this.startDateIndex -= 5;
                var params = new URLSearchParams;
                params.set("startDateIndex", this.startDateIndex.toString());
                this.Http.get(this.BaseURL + 'api/SampleData/WeatherForecasts/', { params: params })
                    .subscribe(result => this.forecasts = result.json(), error => console.error(error));
                break;
            case "Next":
                this.startDateIndex += 5;
                var params = new URLSearchParams;
                params.set("startDateIndex", this.startDateIndex.toString());
                this.Http.get(this.BaseURL + 'api/SampleData/WeatherForecasts/', { params: params })
                    .subscribe(result => this.forecasts = result.json(), error => console.error(error));
                break;
            case "Post":
                console.log("Post * this.forecast=" + JSON.stringify(this.forecast));
                this.Http.post(this.BaseURL + '/api/SampleData/Post/', this.forecast, { headers: this.Headers })
                    .subscribe(result => alert("Posted" + JSON.stringify(result.json())), error => console.error(error));
                break;
        }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json.Linq;

namespace NG_20.Controllers
{
    [Route("api/[controller]/[action]")]
    public class SampleDataController : Controller
    {
        private static string[] Summaries = new[]
        {
            "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
        };

        [HttpGet]
        public IEnumerable<WeatherForecast> WeatherForecasts(int startDateIndex = 0)
        {
            var rng = new Random();
            return Enumerable.Range(1, 5).Select(index => new WeatherForecast
            {
                DateFormatted = DateTime.Now.AddDays(index + startDateIndex).ToString("d"),
                TemperatureC = rng.Next(-20, 55),
                Summary = Summaries[rng.Next(Summaries.Length)]
            });
        }

        [HttpPost]
        public object Post([FromBody] object weatherForecast)
        {
            var forecast = JObject.Parse(weatherForecast.ToString()).ToObject<WeatherForecast>();
            var x = forecast.DateFormatted;
            return weatherForecast;
        }



        public class WeatherForecast
        {
            public string DateFormatted { get; set; }
            public int TemperatureC { get; set; }
            public string Summary { get; set; }

            public int TemperatureF
            {
                get
                {
                    return 32 + (int)(TemperatureC / 0.5556);
                }
            }
        }
    }
}
jimguyer
  • 161
  • 1
  • 8