質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Angular

Angularは、JavaScriptフレームワークです。AngularJSの後継であり、TypeScriptベースで実装されています。機能ごとに実装を分けやすく、コードの見通しが良いコンポーネント指向です。

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

TypeScript

TypeScriptは、マイクロソフトによって開発された フリーでオープンソースのプログラミング言語です。 TypeScriptは、JavaScriptの構文の拡張であるので、既存の JavaScriptのコードにわずかな修正を加えれば動作します。

ASP.NET

ASP.NETは動的なWebサイトやWebアプリケーション、そしてWebサービスを構築出来るようにする為、Microsoftによって開発されたウェブアプリケーション開発フレームワークです。

Q&A

解決済

1回答

7872閲覧

Angularで用意したHttp.postでpostメソッドのhttpリクエストが送れない

cocoalix

総合スコア62

Angular

Angularは、JavaScriptフレームワークです。AngularJSの後継であり、TypeScriptベースで実装されています。機能ごとに実装を分けやすく、コードの見通しが良いコンポーネント指向です。

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

TypeScript

TypeScriptは、マイクロソフトによって開発された フリーでオープンソースのプログラミング言語です。 TypeScriptは、JavaScriptの構文の拡張であるので、既存の JavaScriptのコードにわずかな修正を加えれば動作します。

ASP.NET

ASP.NETは動的なWebサイトやWebアプリケーション、そしてWebサービスを構築出来るようにする為、Microsoftによって開発されたウェブアプリケーション開発フレームワークです。

0グッド

0クリップ

投稿2018/04/19 06:39

編集2018/04/19 08:14

前提

  • ASP.Net WebAPI (Dotnet Core2)
  • Angular CLI: 1.7.4
  • Node: 9.5.0
  • Angular: 5.2.9

実現したいこと

  • ASP.Net WebAPI側で用意したAPIに対して、AngularのHttp.post()を使用してアクセスしたい

発生している問題・エラーメッセージ

  • Chromeの開発者ツールのコンソールに出ているエラーメッセージ
zone.js:2969 OPTIONS http://localhost:5000/api/Example 404 (Not Found) Failed to load http://localhost:5000/api/Example: 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:4200' is therefore not allowed access. The response had HTTP status code 404.

該当のソースコード

  • ASP.Net WebAPI

csharp

1using System; 2using System.Collections.Generic; 3using System.Linq; 4using System.Net; 5using System.Net.Http; 6using System.Threading.Tasks; 7using ExampleApp.Models; 8using Microsoft.AspNetCore.Mvc; 9 10namespace ExampleApp.Controllers{ 11 12 [Route("api/[controller]")] 13 public class ExampleController : Controller { 14 15 [HttpGet] 16 public IEnumerable<NoteModel> Get() 17 { 18 this.Response.Headers.Add("Access-Control-Allow-Origin", "*"); 19 return _notes; 20 } 21 22 [HttpGet("{id}")] 23 public NoteModel Get(int id) 24 { 25 //var found = _notes.Where(x => x.Id == id.ToString()); 26 //if(found.Any()) 27 return _notes.Where(x => x.Id == id.ToString()).FirstOrDefault(); 28 //return _notes[id]; 29 } 30 31 public NoteController(){ 32 _notes.Add(new NoteModel(){Id="1",Detail ="テスト"}); 33 _notes.Add(new NoteModel(){Id="2",Detail ="テスト2"}); 34 } 35 IList<NoteModel> _notes = new List<NoteModel>(); 36 37 [HttpPost] 38 public IActionResult Post([FromBody] NoteModel d) 39 { 40 foreach (var h in this.Request.Headers) { 41 Console.WriteLine($"{h.Key}: {h.Value}"); 42 } 43 if (d == null) return BadRequest(); 44 45 //_notes.Add(d); 46 Console.WriteLine(d); 47 48 return NoContent(); 49 } 50 51 // PUT api/values/5 52 [HttpPut("{id}")] 53 public void Put(int id, [FromBody]string value) 54 { 55 } 56 57 // DELETE api/values/5 58 [HttpDelete("{id}")] 59 public void Delete(int id) 60 { 61 } 62 } 63}
  • ASP.Net WebAPI Cors設定

csharp

1using System; 2using System.Web.Http; 3 4namespace ExampleApp 5{ 6 public static class WebApiConfig 7 { 8 public static void Register(HttpConfiguration config) 9 { 10 config.EnableCors(); 11 12 config.Routes.MapHttpRoute( 13 name: "ExampleApp", 14 routeTemplate: "api/{controller}/{id}", 15 defaults: new { id = RouteParameter.Optional } 16 ); 17 } 18 } 19}
  • Angular

typescript

1import { Injectable } from '@angular/core'; 2import { 3 Headers 4, Http 5, RequestOptionsArgs 6, RequestOptions 7, URLSearchParams 8} from '@angular/http'; 9import { Observable } from 'rxjs/Observable'; 10import 'rxjs/add/operator/map'; 11 12import { Note } from '../note'; 13import { Options } from 'selenium-webdriver/chrome'; 14 15@Injectable() 16export class ApiService { 17 // RestAPIのURL 18 private apiurl = 'http://localhost:5000/api/Example'; 19 20 // コンストラクタで利用するモジュールをインスタンス化 21 constructor(private http: Http) { } 22 23 // 商品一覧取得 24 public getItems(): Observable<Note[]> { 25 console.log(this.apiurl); 26 // リクエストパラメータセット 27 let option: RequestOptions; 28 option = this.setHttpGetParam(this.apiurl); 29 30 // レスポンス返却 31 return this.http.get(this.apiurl, option) 32 .map((response) => { 33 console.log(response); 34 let content; 35 const obj = response.json(); 36 content = { 37 error: null, 38 data: obj 39 }; 40 console.dir(content); 41 return content; 42 43 }); 44 } 45 46 // Http(Get)通信のリクエストパラメータをセットする 47 private setHttpGetParam(url: string): RequestOptions { 48 const options: RequestOptionsArgs = { 49 method: 'get', 50 url: url, 51 }; 52 return new RequestOptions(options); 53 } 54 55 public post(detail: String): void { 56 const note = new Note(); 57 note.Detail = detail; 58 note.IsChecked = false; 59 note.Id = '0'; 60 const json = JSON.stringify(note); 61 62 const headers = new Headers({ 63 'Content-Type': 'plane/text' 64 , 'Access-Control-Origin': '*' 65 , 'x-requested-with': 'accept' 66 , 'Cache-Control': 'no-cache' 67 }); 68 const options = new RequestOptions({'headers': headers}); 69 this.http.post(this.apiurl, json, options).toPromise() 70 .then(x => console.log(x.status)) 71 .catch(e => console.log(e)); 72// this.http.post(this.apiurl, json, {'headers' : headers}) 73// .map((res) => console.log(res.status)) 74// .subscribe(); 75 } 76}

試したこと

  • ASP.Net WebAPI側で用意したGetやPost APIにはPostmanなどのRESTful API接続ツールで接続できることを確認した
  • また、PostmanでのAPI接続テスト時に各メソッド(POST,GET等)にブレークをはって、アクセスが確かに処理されていることを確認した
  • ASP.Net WebAPI側にCorsを有効にする設定を追加した

補足情報(FW/ツールのバージョンなど)

  • FW/ツールについては概要欄記載のため概要欄を確認してください
  • Mac/Windows問わず発生しています
  • GETメソッドは意図した通りに値を返しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2018/04/19 07:36

エラーメッセージに preflight とあるので、クロスドメインの問題があるように思えますが、そのあたりは確認してますか?
cocoalix

2018/04/19 08:16 編集

クロスドメインの問題については不完全ながら認識していました。そのためC#側と同様にAngularのPOST通信のリクエストヘッダに `'Access-Control-Origin': '*'` をつけています。今、この指摘を受けたことで再度調べ、サーバサイドの設定が必要のように見えましたのでそのコードを追加しましたが、状況は改善されませんでした。追加した内容は質問に反映します。
guest

回答1

0

ベストアンサー

クロスドメインの問題については不完全ながら認識していました。そのためC#側と同様にAngularのPOST通信のリクエストヘッダに 'Access-Control-Origin': '*' をつけています。

エラーメッセージに preflight とあることだけからの想像ですが、プリフライトリクエストを処置するためにはサーバー側での対応も必要になります。

具体例は、ASP.NET でホスティングしている WCF サービスの場合ですが、以下の記事を見てください。

クロスドメインの WCF サービス
http://surferonwww.info/BlogEngine/post/2016/12/27/wcf-service-in-cross-domain.aspx

ただ、Core とのことですので、上に紹介した記事のように Global.asax の Application_BeginRequest での対処ができるかどうか自分はわかりませんが・・・

投稿2018/04/19 08:42

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

cocoalix

2018/04/24 10:14 編集

仰る通り、ASP.Net WebAPI側にてプリフライトリクエストに対応するコードがありませんでした。 MSDNによると、Setup.csにある`Configure()`にてCORSの対応を設定できるとのことでしたので、 設定したところリクエストがエラーとならず処理されました。 `Post()`内に実行が通っていることをブレークポイントを張ってリクエストを流すことで確認済です。 https://docs.microsoft.com/ja-jp/aspnet/core/security/cors この回答はクライアント側かサーバ側か、問題がどちらにあるのかさえわかっていなかった私を問題解決へと導きました。 最後に、ご返答遅くなり申し訳ありません。 的確なご指導、ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問