[不确定我的请求出了什么问题,但显然控制器操作未收到我的帖子。我想使用防伪令牌发布此表单,我也想使用ajax请求。因此,我没有使用包含防伪令牌的默认aspnet核心形式,而是使用了html helper @Html.AntiforgeryToken()
。知道问题出在哪里吗?
@model RunViewModel
@{
ViewData["Title"] = "Run";
}
<h1 class="text-info">@ViewData["Title"]</h1>
<form id="run-form">
@Html.AntiForgeryToken()
<div class="form-group">
<label asp-for="InstanceName"></label>
<input asp-for="InstanceName" class="form-control" placeholder="Enter an instance name here..." />
</div>
<div class="form-group">
<label asp-for="DatabaseName"></label>
<input asp-for="DatabaseName" class="form-control" placeholder="Enter a database name here..." />
</div>
<div class="form-group">
<label asp-for="FolderPath"></label>
<input asp-for="FolderPath" class="form-control" />
</div>
<div class="col-3 offset-4">
<button type="submit" class="btn btn-primary">Run!</button>
</div>
</form>
@section Scripts {
<script>
$("#run-form").submit(function () {
var data = $('#run-form').serializeArray();
console.log(data);
alert($('input:hidden[name="__RequestVerificationToken"]').val());
$.ajax({
type: 'POST',
url: '/Run/Run',
contentType: 'application/json',
headers: { RequestVerificationToken: $('input:hidden[name="__RequestVerificationToken"]').val() },
data: JSON.stringify(data),
success: function (data) {
if (data.status = "success") {
alert("Database has been updated !"); //TODO : Mettre un div vert avec un message à la place.
}
},
error: function () {
alert("An error occured 2!"); //TODO : Mettre un div rouge avec un message à la place.
}
});
//event.preventDefault();
});
</script>
}
和控制器部分是:
[HttpPost]
[ValidateAntiForgeryToken]
public JsonResult Run(string jsonObj)
{
//TODO : CHECK JSONOBJ
RunViewModel model = JsonSerializer.Deserialize<RunViewModel>(jsonObj);
try
{
//Call a service here...
}
catch (Exception ex)
{
//Renvoyer un message
}
return Json(model);
}
并且视图模型为:
public class RunViewModel
{
[Required]
[Display(Name="Instance name : ")]
public string InstanceName { get; set; }
[Required]
[Display(Name="Database name : ")]
public string DatabaseName { get; set; }
[Required]
[Display(Name="SQL folder path : ")]
public string FolderPath { get; set; }
/// <summary>
/// Liste ordonnée des fichiers, regroupés par version, à lancer sur la base de données suivant la version actuelle de la base de données.
/// </summary>
public IOrderedEnumerable<IGrouping<Version, string>> SqlFilesGroupedByVersion { get; set; }
}
jqXHR.success(),jqXHR.error()和jqXHR.complete()回调在jQuery 1.8中将被弃用。要准备将其最终删除的代码,请改用jqXHR.done(),jqXHR.fail()和jqXHR.always()。
使用ModelState验证来验证模型
[使用OnClick方法提交表单以避免e.reeventDefault()。
我根据您的要求在下面提供了一个完整的示例(请阅读所有内联注释-
型号:-
public class RunViewModel
{
[Required]
[Display(Name = "Instance name : ")]
public string InstanceName { get; set; }
[Required]
[Display(Name = "Database name : ")]
public string DatabaseName { get; set; }
[Required]
[Display(Name = "SQL folder path : ")]
public string FolderPath { get; set; }
/// <summary>
/// Liste ordonnée des fichiers, regroupés par version, à lancer sur la base de données suivant la version actuelle de la base de données.
/// </summary>
public IOrderedEnumerable<IGrouping<Version, string>> SqlFilesGroupedByVersion { get; set; }
}
public class ValidationError
{
public string PropertyName { get; set; }
public string[] ErrorList { get; set; }
}
Controller:-
public class RunController : Controller
{
[HttpGet]
// GET: Run/Save
public ActionResult Save()
{
var model = new RunViewModel();
return View(model);
}
// POST: Run/Save
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Save(RunViewModel model)
{
var status = "Failed";
var massage = "";
try
{
//If modelstate validation need
if (!ModelState.IsValid)
{
return Json(new
{
status,
massage,
model,
errorList = GetModelStateErrors(ModelState).ToList()
});
}
else
{
//Write your code
status = "success";
massage = "Database has been updated !";
}
}
catch (Exception ex)
{
massage = ex.Message;
}
return Json(new
{
status,
massage,
});
}
public IEnumerable<ValidationError> GetModelStateErrors(ModelStateDictionary modelState)
{
var errors = (from m in modelState
where m.Value.Errors.Count() > 0
select
new ValidationError
{
PropertyName = m.Key,
ErrorList = (from msg in m.Value.Errors
select msg.ErrorMessage).ToArray()
})
.AsEnumerable();
return errors;
}
}
Save.cshtml:-
@model RunViewModel
@{
ViewData["Title"] = "Run";
}
<h1 class="text-info">@ViewData["Title"]</h1>
<style>
.field-validation-valid{
color:#FF0000;
}
</style>
<form id="run-form">
@Html.AntiForgeryToken()
<div class="form-group">
<label asp-for="InstanceName"></label>
<input asp-for="InstanceName" class="form-control" placeholder="Enter an instance name here..." />
<span asp-validation-for="InstanceName"></span>
</div>
<div class="form-group">
<label asp-for="DatabaseName"></label>
<input asp-for="DatabaseName" class="form-control" placeholder="Enter a database name here..." />
<span asp-validation-for="DatabaseName"></span>
</div>
<div class="form-group">
<label asp-for="FolderPath"></label>
<input asp-for="FolderPath" class="form-control" />
<span asp-validation-for="FolderPath"></span>
</div>
<div class="col-3 offset-4">
<button type="button" id="btnSubmin" class="btn btn-primary">Run!</button>
</div>
</form>
@section Scripts {
<script>
$("#btnSubmin").on("click", function () {
var valToken = $('input:hidden[name="__RequestVerificationToken"]').val();
var model = getFormData('run-form');
$.ajax({
type: 'POST',
url: '/Run/Save',
contentType: 'application/x-www-form-urlencoded',//set a Content-Type of application/json; charset=UTF-8 When Call API,application/x-www-form-urlencoded is the default contentType
headers: { RequestVerificationToken: valToken },
dataType: 'json',
data: model,//you need to pass json string
}).done(function (data) {
if (data.status === "success") {
alert("Database has been updated !"); //TODO : Mettre un div vert avec un message à la place.
} else {
displayValidationErrors(data.errorList);
}
}).fail(function (data) {
alert("An error occured 2!"); //TODO : Mettre un div rouge avec un message à la place.
});
/*
The jqXHR.success(), jqXHR.error(), and jqXHR.complete() callbacks will be deprecated in jQuery 1.8. To prepare your code for their eventual removal, use jqXHR.done(), jqXHR.fail(), and jqXHR.always() instead.
*/
});
//Show Validation Message
function displayValidationErrors(errors) {
$.each(errors, function (idx, validationError) {
$("span[data-valmsg-for='" + validationError.propertyName + "']").text(validationError.errorList[0]);// if not working then captilized ex: errorList to ErrorList,propertyName to PropertyName
});
}
//Convert to Json From InputForm
function getFormData(formId) {
var $form = $("#" + formId);
var unindexed_array = $form.serializeArray();
var indexed_array = {};
$.map(unindexed_array, function (n, i) {
indexed_array[n['name']] = n['value'];
});
return indexed_array;
}
</script>
}
(已测试)