1

Good day StackOverflow! I've opened up a new question because I am a total beginner with Web Services and the current topics similar to my question doesn't make any sense to me at the moment. I am very welcome to learn something new. I would be happy to receive response and support from the community.

Currently I am having a Web Development training in a company and one of our task is to create a Web Service using "Microsoft ASP.NET Core 2.0 Web API" using MVC and enabling CORS for our Aurelia application.

My Aurelia app is hosted in http://localhost:9000/ and the webservice is in http://localhost:5000/ as tests.

Here are the problems that I've encountered and my observations:

  1. Whenever I run my Aurelia app, I am getting this error on the browser console: "Failed to load http://localhost:5000/api/sample: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:9000' is therefore not allowed access." Is there any configuration on my C# code that i need to add in order for this error to go away?

  2. I used PostMan in order to check if the web service is working, and yes it did work. So I was wondering what was wrong if I access the web service from my Aurelia application, it generates an error. I guess the error is in the client side? Here is the screenshot of the PostMan request and response.

PostMan request and response worked

  1. If I pass an object from my aurelia app to the web service as HTTP POST request, does the web service understands/maps right away the object values received?

    1. And also on the Web API Debug Console, it says: "Request method POST not allowed in CORS policy."

To make it simpler, I have this code on my Aurelia app.ts written in TypeScript which requests the sample data through HTTP Post verb:

import { inject } from 'aurelia-framework';
import { HttpClient } from 'aurelia-http-client';

@inject(HttpClient)
export class WebAPITest {

  private httpClient: HttpClient;
  private static readonly BASE_URL = `http://localhost:5000/api/`;
  private message = `Web API Access Test! Pls. check the console.`;

  constructor(httpClient: HttpClient) {
    this.httpClient = httpClient;
    this.httpClient.configure(requestBuilder => {
      requestBuilder.withBaseUrl(WebAPITest.BASE_URL);
      requestBuilder.withHeader('Content-Type', 'application/json'); // (?) Need clarifications.
    });
  }

  activate() {
    let sampleData = new SampleData();
    return this.httpClient.post(`sample`, sampleData)
      .then(response => {
        if (response.isSuccess) {
          this.data = response.content;
          console.log(`SampleData Web Service Call SUCCEED!`);
        } else {
          console.log(`SampleData Web Service Call FAILED!`);
        }
    });
  }
}

export class SampleData {
   public name: string;
   public age: number;

   constructor() {
    this.name = "Garfield";
    this.age = 5;
   }
}

Here is the code of my ASP.NET Core 2.0 MVC Web API: (Startup.cs)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;

namespace Syslog.Web.GradeSheet.Backend
{
    public class Startup
    {
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc();
            services.AddCors();
        }

        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            // For now it only accepts requests from localhost port 9000 which is the seat of our Aurelia applications.
            app.UseCors(corsPolicyBuilder => {
                corsPolicyBuilder.WithOrigins("http://localhost:9000");
            });

            app.UseMvc();

            // Normally this will be fired up when no route has been matched.
            app.Run(async (context) =>
            {
                await context.Response.WriteAsync("Welcome To GradeSheet Web Service! MVC has not found any Route that has been matched yet.");
            });
        }
    }
}

Here is the code of my ASP.NET Core 2.0 MVC Web API: (SampleController.cs):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;

namespace Syslog.Web.GradeSheet.Backend.Controllers
{
    [Route("api/[controller]")]
    public class SampleController : ControllerBase
    {
        [HttpPost]
        public IActionResult getSampleObject([FromBody] SampleData sampleData) {

            if(ModelState.IsValid) {
                System.Diagnostics.Debug.WriteLine($"PRINTED: {sampleData.name} is {sampleData.age} years old.");
            } else {
                System.Diagnostics.Debug.WriteLine("ModelState is not Valid.");
            }


            return Ok($"Ok, got it, {sampleData.name}! You are {sampleData.age} years old.");
        }
    }

    public class SampleData {
        public string name { get; set; }
        public int age { get; set; }
    }
}

Thank you very much for the time reading my problem. I would appreciate any solutions, recommendations, additional information or criticisms on my code. Have a nice day.

Jerald James Capao
  • 175
  • 1
  • 1
  • 7
  • I don't know why your MVC is not working, but Postman is working because it does not do the cors validations that a browser would do. Use the browser dev tools to see the request/response network trace. – Crowcoder May 11 '18 at 10:17
  • The error is not client side, can you try adding the following to your CORS builder: `.WithOrigins(...).AllowAnyHeader().AllowAnyMethod().AllowCredentials()`? – Jesse May 11 '18 at 11:40
  • @JessedeBruijne Exactly! I added this code and it works fine now. Hehe thanks! app.UseCors(corsPolicyBuilder => { corsPolicyBuilder.WithOrigins("http://localhost:9000", "http://localhost:9001"); corsPolicyBuilder.WithHeaders("content-type"); corsPolicyBuilder.WithMethods("GET", "POST", "PUT"); }); – Jerald James Capao May 11 '18 at 11:52

1 Answers1

1

The issue is in the MVC Startup here. You're not fully configuring your CORS builder, you're only configuring the allowed origins, but not the rest of the configuration.

If you change it to this, it should work fine:

app.UseCors(corsPolicyBuilder => {
  corsPolicyBuilder.WithOrigins("http://localhost:9000").AllowAnyHeader().AllowAnyMethod().AllowCredentials();
});
Jesse
  • 3,522
  • 6
  • 25
  • 40