はじめに
同僚がデータ修正ツールを作成することになり、サンプル的に久しぶりに ASP.NET(C#) + MVC + PostgreSQL でテキストボックスにSQLを入力してボタンをクリックすれば、SQLの結果をグリッド(Handsontable)に表示させるだけのアプリケーションを作成したのですが、POSTした際に「リソースが見つかりません」のエラーで嵌りました。
現象
テキストボックスにSQLを入力してボタンをクリックすると、最初はSQLの結果がグリッド(Handsontable)に表示されるし、C#の部分にブレークポイントすればデバッグできるのですが、2回目以降になると「リソースが見つかりません」の例外エラーとなり、エラー詳細としては「GetSQLDataのコントローラーが見つからないか、IControllerを実装していません。」となります。
GetSQLData
というのは、今回MVCのコントローラーで独自に作成したメソッドになります。
ネット検索の対応でも解決できず、メソッド名をGetSQLData2
とかGetSQLData3
のように名前を変更すると、デバッグでトレースできて表示までできるのですが、やはり2回目以降になると「リソースが見つかりません」のままです。
public class HomeController : Controller
{
// GET: Home
public ActionResult Index()
{
@ViewBag.MsgErrCommException = "通信エラーが発生しました。";
return View();
}
/// <summary>
// SQL文の実行結果を取得する
/// </summary>
/// <returns>結果</returns>
[HttpPost]
public JsonResult GetSQLData(SendSQLPostViewDataModels data)
{
object result = new { success = false, message = "", resultData = "" };
try
{
ListViewModel vm = new ListViewModel();
ResultData resultData = vm.GetResultData(data.SQL);
result = new { success = true, message = "Success", resultData = resultData };
}
catch (Exception ex)
{
result = new { success = false, message = ex.Message, resultData = "" };
}
return Json(result, JsonRequestBehavior.AllowGet);
}
}
function preview() {
let that = this;
let param = {
FactryList: null,
SQL: $("#txtSQL").val(),
};
let process = function (data) {
if (data.success) {
hot.loadData(data.resultData.Data);
hot.updateSettings({
colHeaders: data.resultData.Header
});
}
}
postAjax('GetSQLData', JSON.stringify(param), process);
}
// PUT用非同期処理
function postAjax(method, data, callback) {
jQuery.ajax({
url: method,
type: 'POST',
dataType: 'json',
contentType: 'application/json; charset=utf-8',
data: data,
async: true,
processData: false,
cache: false
}).fail(function (xhr, status, error) {
let msg = '@ViewBag.MsgErrCommException' + '\n' + xhr.status + ' ' + error;
alert(xhr.responseText);
}).done(function (data) {
if (data.success)
callback(data);
else
alert(data.message);
});
}
対応
「GetSQLDataのコントローラーが見つからないか、IControllerを実装していません。」というエラーに着目、もしやURLの指定が間違っているのではないかと思い直し下記のように修正してみました。
postAjax('GetSQLData', JSON.stringify(param), process);
↓
postAjax('/Home/GetSQLData', JSON.stringify(param), process);
結果は正解でした。
これにより、2回目以降でも問題なく動作するようになりました。
原因
対応から原因を探れば、URLの指定が間違っていたことになります。Home/Index.cshtml から実行したので、/Home/
の指定は不要だとおもったわけです。
しかも、最初だけは正しく動くのですから記載が間違っているとは気が付き難いですよね。
最後に
これもキャッシュのようなものなんでしょうか、Visual Studio上で最初だけは動くからといって正しいと思うのは間違いのもと。ハマりましたね。