web-dev-qa-db-ja.com

AJAX ASP.NET MVC6への投稿コントローラーのアクションメソッドとパラメーターがnull

ASP.NET MVCで奇妙な問題が発生し、AJAXpost。ID'lnkGetExpirDates 'のページにアンカータグがあります。ユーザーがクリックすると、単純にしようとしています。このハードコードされたデータをコントローラーに送信して、パラメーターとして使用し、結果をページに返すことができるようにします。

ただし、コントローラーでは、パラメーターは常にnull /デフォルト値です。以下の私のコードを見て、私がばかげた間違いか何かをしているのかどうか私に知らせてください。

これが私のAJAX post:

$("#lnkGetExpirDates").click(function () {
    e.preventDefault();

    var data = {
        StartDate: "1/19/2016",
        EndDate: "4/19/2016",
        ProductType: "New",
        Count: 1
    };


    $.ajax({
        url: '/Products/GetExpirationDates',
        type: 'POST',
        data: JSON.stringify(data),
        contentType: 'application/json; charset=utf-8',
        dataType: 'html',
        success: function (data) {
            $('#ExpirationDates').val(data);
        }
    });

});

これが私のコントローラーのアクションメソッドです:

// POST: Product/GetExpirationDates
[HttpPost]
//[ValidateAntiForgeryToken]
public IActionResult GetExpirationDates(GetExpirationDatesViewModel vm)
{
    // TODO: Get expiration dates and return them in the response

    return View();
}

これがGetExpirationDatesViewModelです:

public DateTime StartDate { get; set; }
public DateTime EndDate { get; set; }
public string ProductType { get; set; }
public int Count { get; set; }

モデルをまったく使用せずに、startDate、endDate、productType、Countなどのパラメーターをアクションメソッドに追加するだけでこれを試しても、すべてがnullになることに注意してください。

5
Blake Rivell

コンテンツタイプの値をapplication/jsonとして指定すると、サーバーに対して行われたajaxリクエストは、リクエストの本文()でjsオブジェクトをリクエストペイロードとしてjson形式)。したがって、アクションメソッドでは、[FromBody]属性を使用する必要があります。

public IActionResult GetExpirationDates([FromBody] GetExpirationDatesViewModel vm)
{
   return View();
}

これもまた別のモデル/タイプであるプロパティを持つ複雑なjsオブジェクトを送信する場合にこれを行う必要があります

ただし、送信するデータはフラットビューモデルです。したがって、jsオブジェクトをjsonで文字列化する必要はありません。また、複雑なjsオブジェクトの文字列化されたバージョンを送信しないように、コンテンツタイププロパティを削除することもできます。

これは正常に機能するはずです。

$.ajax({
    url: '/Products/GetExpirationDates',
    type: 'POST',
    data: data,      
    dataType: 'html',
    success: function (data) {
        console(data);
    }
});

上記のコードは、jsオブジェクトをキーと値のペア(通常のフォームデータ)として送信し、モデルバインダーはフォームデータをサーバー内のビューモデルオブジェクトにマップできるようになります。詳細な説明については、 この投稿 をご覧ください。

また、Url.Actionヘルパーメソッドを使用して、アクションメソッドへの適切な相対URLを生成することをお勧めします。

url: '@Url.Action("GetExpirationDates","Products")',

上記は、jsコードがレイザービュー内にある場合に機能するはずです。コードが外部jsファイル内にある場合は、 この投稿 で説明されているソリューションを使用してください。

12
Shyju