トップ回答者
VB MVC5でAjaxが成功しない。

質問
-
いつもお世話になります。
Visual Studio 2015 Update3 pro. のVBで、Webアプリを作ろうとしています。Ajaxのところで上手くいかずに右往左往している状況です。VSで新しいWeb APIプロジェクトを作成して、以下のものを書き加えました。
(1)読み取り/書き込みのあるWebAPI2コントローラーを作成して、FoodsController.vb
Imports System.Net Imports System.Web.Http Namespace Controllers Public Class FoodsController Inherits ApiController Private foods As String() = {"bread", "rice", "noodles", "sushi", "spaghetti", "pizza"} ' GET: api/Foods Public Function GetValues() As IEnumerable(Of String) Return foods End Function ' GET: api/Foods/5 Public Function GetValue(ByVal id As Integer) As String If id > 0 And id <= foods.Length Then Return foods(id - 1) Else Return "I don't know." End If End Function End Class End Namespace
これを実行して、
http://localhost:49286/api/foods にアクセスすると、["bread","rice","noodles","sushi","spaghetti","pizza"]
http://localhost:49286/api/foods/4 にアクセスすると、"sushi"
http://localhost:49286/api/foods/100 にアクセスすると、"I don't know."
が戻ってくることを確認しました。
次に、MVC5コントローラ-空 を作成して、FoodlistController.vb
Namespace Controllers
Public Class FoodlistController Inherits Controller ' GET: Foodlist Function Index() As ActionResult Return View() End Function Function Food(id As Integer) As ActionResult Return View(id) End Function End Class End Namespace
と、 Foodlist/Index.vbhtml
@Code ViewData("Title") = "Index" End Code <h2>Please Push Button</h2> <button id="display" class="btn btn-success">Display List</button> <h2>Foods List</h2> <div id="list"></div> <h2>End of List</h2> @Section scripts <script> $("#display").click(function () { var url = "api/foods/"; $.getJSON(url) .done(function (data) { var html = "<ul>"; $.each(data, function (index, value) { html += "<li>" + value + "</li>"; }) html *= "/ul>"; $("#list").html(html); }) .fail(function(data){ $("#list").text("Error on Ajax!!!"); }); }); </script> End section
を書きました。そして、実行して、[Display List]ボタンを押しても、”Error on Ajax!!!”という失敗メッセージしか現れません。
何をすれば、Ajaxが成功するようになるでしょうか?よろしくお願いします。
回答
-
こんにちは。
//var url = "api/foods/"; var url = "/api/foods/";
ではないでしょうか。
あと、ulが閉じれてないようです。//html *= "/ul>"; html += "</ul>";
- 編集済み いわさ Tak1waMVP, Moderator 2016年7月7日 1:59
- 回答としてマーク hiroshi.tsuchida 2016年7月7日 4:00
すべての返信
-
ざっと見たかぎりでは問題になりそうなところは見当たらないです。
質問者さんのコードを詳しく調べる前に一つお願いできますか?
それは、質問者さんの方で Fidder などのキャプチャツールを使って、要求と応答がどうなっているか調べることです。
期待した GET 要求が出ているか、期待した JSON 文字列が返ってきているかを調べてください。うまく行くと以下のようになるはずです。
#開発環境(VS だけではなくて、OS、IIS、jQuery のバージョン、ブラウザは何かなども)を書いてください。
#もし公開されているどこかの Web の記事がベースになっているのであればその URL を書いてください。
- 編集済み SurferOnWww 2016年7月7日 1:48 「jQuery のバージョン」追記
-
こんにちは。
//var url = "api/foods/"; var url = "/api/foods/";
ではないでしょうか。
あと、ulが閉じれてないようです。//html *= "/ul>"; html += "</ul>";
- 編集済み いわさ Tak1waMVP, Moderator 2016年7月7日 1:59
- 回答としてマーク hiroshi.tsuchida 2016年7月7日 4:00
-
一つ気がつきました。
> 次に、MVC5コントローラ-空 を作成して、FoodlistController.vb
というのは、Web API 用に作ったプロジェクト / アプリケーションとは別プロジェクト / 別アプリケーションですか?
AJAX 呼び出しを行うわけですから、2 つのプロジェクト / アプリケーションは同じドメイン内にないとダメです。(AJAX の約束事)
IIS Express 上で実行すると 2 つのプロジェクト / アプリケーションがどういう関係で実行されるのかは知りませんが、そのあたり(「MVC5コントローラ-空」アプリから「Web API」アプリが呼び出せてない)に問題がありそうな気がします。
呼び出し側も同じプロジェクト / アプリケーションに実装してください。
MVC5 は多少違うかもしれませんが、テンプレートを使って作ると全体の構成は以下のようになるのでは?
ASP.NET Web API を使ってみよう: MVC 4 新機能シリーズ
https://blogs.msdn.microsoft.com/chack/2012/02/24/asp-net-web-api-mvc-4-2/であれば、上記の記事の手順 5 に書いてあるように、その中の(同じプロジェクト / アプリケーションの)Index.cshtml に Web API を呼び出す jQuery のスクリプトを実装して試してみてください。
Fiddler などのパケットキャプチャツールで調べると、どこに問題があるかが容易に見つかると思います。だから、そういうことを前のレスで提案してます。使えるようになりましょう。
-
SurferOnWwwさま
いつもいろいろ教えてくださり、感謝しています。
教えていただいた、Fidderを早速ダウンロードして試してみます。なかなか多彩な機能の開発ツールみたいですね。
大きな収穫のひとつでした。ありがとうございます。当初の問題は、この後のTak1waさんの回答で氷解しました。私のつまらない思い込みでしたね。
いろいろ煩わせてすみません。ちなみに、開発環境はAzureのVMで、OSはWindows Server2012R2 です。職場の事務用パソコンではメモリ不足になるので。
参考にしたものは、最近2週間ぐらいに10冊ぐらい関連書籍を斜め読みしましたが、一番頼りにしているのは、
山田祥寛氏の「ASP.NET MVC5実践プログラミング」(秀和システム)で、P.435からAjaxの説明があります。いろいろとありがとうございました。
-
SuferOnWwwさま
一つのMVC5のWeb APIプロジェクトを新規作成すると、Webアプリケーションの機能も同時に構築されるみたいです。
今回は、この方法でしたので、同一のサイトに2つの機能があります。更にこのサイトにはHelpコントローラが付いてきて、
自作したWeb APIのヘルプ情報を自動的に収集して表示してくれる仕組みもついていました。
web APIの実装を秘密にする必要がない場合はとても便利ですが、
秘密にしておこうと思っても知らないところででAPIのヘルプがみられてしまうというのも少し恐ろしいことかなと思いました。教えていただいたFiddlerをインストールして試しています。なかなか面白いです。ありがとうございます。
-
> 当初の問題は、この後のTak1waさんの回答で氷解しました。私のつまらない思い込みでしたね。
「つまらない思い込み」ということはなくて、スラッシュ '/' は結構深い話だと思うのですが。
特に最初のスラッシュ '/' の有無による違いは重要で、それによってブラウザが要求をかける際のパスが違ってくるということを理解していますか?
理解していたら失礼しました。以下のレスはスルーしてください。
"/api/foods" のように最初にスラッシュ '/' を付けると「サイト ルート相対パス」、"api/foods" のようにすると「現在のページ パスに対して解決される相対パス」になります。詳しい説明は以下の記事を見てください。
ASP.NET Web サイトのパス
https://msdn.microsoft.com/ja-jp/library/ms178116(v=VS.100).aspx今回の問題は、Foodlist/Index.vbhtml からでは "api/foods" のような「現在のページパスに対して解決される相対パス」ではパスが通らなかったからで、"/api/foods" としたらパスが開発環境での 「サイト ルート相対パス」即ち http://<hostname>/api/foods となったので問題が解決したのだと思います。
しかし、例えば実際の運用環境で、アプリケーションとして Web API をデプロイする場合、URL は http://<hostname>/<appname>/api/foods というようになるはずですが、これを jQuery.getJSON で url を "/api/foods" として要求したのでは HTTP 404 エラーになるはずです(http://<hostname>/api/foods を要求するので)。
最後のスラッシュ(「トレーリングスラッシュ」という)にも意味があって、それに関わる問題もあります。(特に SEO 対策)
URLの終りに「/」(スラッシュ)は必要?、不要?
https://www.suzukikenichi.com/blog/do-we-need-a-trailing-slash-at-the-end-of-url/RESTful API ではちょっと違う意味があって "But from the original paper on REST a full (not ending in /) URL names a resource, while one ending in a slash '/' is a resource group" ということだそうです。(original paper は調べてませんが)
Trailing slash in RESTful API
http://programmers.stackexchange.com/questions/186959/trailing-slash-in-restful-api