ASP.NET 5 MVC 6アプリケーションで、Ajaxを使用して一部のデータをコントローラーに投稿します。私はすでにASP.NET MVC 5でこれを行っており、空のASP.NET MVC 5プロジェクトでまったく同じコードをテストして動作しましたが、新しいバージョンではできませんし、理由もわかりません。 Ajax呼び出しを使用すると、コントローラーにアクセスできます。モデルは作成されますが、フィールドはnull(またはブール値の場合はfalse)です。ここに私のコードがあります:
script.js:
var data = {
model: {
UserName: 'Test',
Password: 'Test',
RememberMe: true
}
};
$.ajax({
type: "POST",
url: "/Account/Login/",
data: JSON.stringify(data),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (msg) {
// Do something interesting here.
}
});
AccountController.cs:
[HttpPost]
public JsonResult Login(LoginViewModel model)
{
if (ModelState.IsValid)
{
//var result = await SignInManager.PasswordSignInAsync(model.UserName, model.Password, model.RememberMe, shouldLockout: false);
//if (result.Succeeded)
//{
// //return RedirectToLocal(returnUrl);
//}
ModelState.AddModelError("", "Identifiant ou mot de passe invalide");
return Json("error-model-wrong");
}
// If we got this far, something failed, redisplay form
return Json("error-mode-not-valid");
}
LoginViewModel.cs:
public class LoginViewModel
{
[Required]
[Display(Name = "UserName")]
[EmailAddress]
public string UserName { get; set; }
[Required]
[DataType(DataType.Password)]
[Display(Name = "Password")]
public string Password { get; set; }
[Display(Name = "Remember me?")]
public bool RememberMe { get; set; }
}
何か案は ?ありがとう
JSONを使用している場合は、MVC6でFromBodyを明示的に使用する必要があります
public JsonResult Login([FromBody]LoginViewModel model)
[〜#〜] edit [〜#〜]
さまざまなエラーが混在していると思います。リクエストの作成方法を説明します。
content-type 必須:application/json
リクエスト本文must be JSON形式(JasonLindが提案したとおり):
{
UserName: 'Test',
Password: 'Test',
RememberMe: true
};
これは、リクエストを検査するとき(chromeデバッガーツールF12)またはフィドラーのようなリクエストインスペクターを使用するときに表示されるものです。
UserName=Test&Password=Test&RememberMe=true
の形式で何かが表示された場合、それは間違っていることになります。それがフォーム形式です。
model
変数は必要ありません。 「ラッパー」でリクエストが表示された場合は、削除する必要があります。
自分でBindModelを実装できます! JSON文字列を取得し、エンティティに逆シリアル化します。
public class JsonBinder<T> : System.Web.Mvc.IModelBinder
{
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
using (var reader = new System.IO.StreamReader(controllerContext.HttpContext.Request.InputStream))
{
//set stream position 0, maybe previous action already read the stream.
controllerContext.HttpContext.Request.InputStream.Position = 0;
string json = reader.ReadToEnd();
if (string.IsNullOrEmpty(json) == false)
{
JavaScriptSerializer serializer = new JavaScriptSerializer();
object jsonData = serializer.DeserializeObject(json);
return serializer.Deserialize<T>(json);
}
else
{
return null;
}
}
}
}
jsonBinderを次のようなpostメソッドに設定します
[HttpPost]
public JsonResult Login([ModelBinder(typeof(JsonBinder<LoginViewModel>))] LoginViewModel model)
{
if (ModelState.IsValid)
{
//var result = await SignInManager.PasswordSignInAsync(model.UserName, model.Password, model.RememberMe, shouldLockout: false);
//if (result.Succeeded)
//{
// //return RedirectToLocal(returnUrl);
//}
ModelState.AddModelError("", "Identifiant ou mot de passe invalide");
return Json("error-model-wrong");
}
// If we got this far, something failed, redisplay form
return Json("error-mode-not-valid");
}
他の解決策
DataContractをModelのクラスに設定し、DataMemberをクラスのプロパティに設定できることがわかりました。
このようにクラスを編集します
[DataContract]
public class LoginViewModel
{
[DataMember]
public string UserName { get; set; }
[DataMember]
public string Password { get; set; }
[DataMember]
public bool RememberMe { get; set; }
}
ライブラリ参照「System.Runtime.Serialization」を追加する必要があります
それがうまくいくことを願っています。
わかりました。解決策は見つかりましたが、それでも私にとっては奇妙なことです... content-type
リクエストから。
$.ajax({
type: "POST",
url: "Account/Login",
data: data,
success: function (msg) {
// Do something interesting here.
}
});
ウォッチャーのおかげで解決策を見つけました:) Request変数を見て、Request.Formが常に例外をスローすることを発見しました。間違ったcontent-typeを使用したと言ったので、content-type
私のajaxの投稿から、それは魅力のように働いた。私は、あなたが作るすべてのajax投稿について、あなたのRequest.Formが正しく記入されることに注意する必要があると思います
[〜#〜] edit [〜#〜]:このソリューションは、接続データのような非JSONデータ(非常に単純なデータ)を投稿できる場合にのみ機能します。しかし、リストのような複雑なデータを投稿したい場合、それはもう機能しません...
あなたの問題はMVC6がjQueryではないということです。 $ .ajax()は "data"をチェックし、その形式を知っているため、コンテンツタイプを設定します。また、約束の方法で$ .ajaxを使用する必要があります。
約束の有利な点を確認してください ここ
また、フォームを選択し、次のようにオブジェクトに変換します
$('.anyForm').on('submit', fucntion(){
//you have the form in JSON format
var data = $(this).serializeObject()
})
here はserializeObject()メソッドであり、デフォルトではjQueryにはありません。
すべきではない:
var data = {
UserName: 'Test',
Password: 'Test',
RememberMe: true
};