当 Ajax 将参数传递给控制器并且模型由于数据注释而无效时如何 return 错误?
How to return errors when Ajax passes parameter to controller and model is invalid due to data annotations?
我有一个 ajax post 调用控制器操作并传递用户(我)输入的参数。
我正在使用数据注释来验证控制器操作中的模型。如果我输入无效值(或没有值)并且 运行 ajax:
- 调用控制器动作
- 发现模型无效(符合预期)
- 变量"result"定义如预期,包含模型、错误等
问题: return 似乎被忽略,响应为 500(内部服务器错误)。
此时我可以将状态代码设置为 200 来处理成功回调中的错误,但我无法用这个(在控制器操作中)覆盖它:
HttpContext.Response.TrySkipIisCustomErrors = true;
HttpContext.Response.StatusCode = (int)System.Net.HttpStatusCode.OK;
和这个(在 web.config 中):
<httpErrors errorMode="Custom" existingResponse="PassThrough"/>
如果我可以从中检索模型的错误,我也可以return将一个对象连接到错误回调,但从我所读的内容来看,这似乎是不可能的。
我搜索了那么多 post 和博客,这些似乎只适用于找到我不太能应用(技术上或概念上)的相同少数解决方案。
问题: 如何在传递给控制器的参数上保留数据注释并强制执行包含模型错误的某种对象的 return?
Ajax:
$('#apply-theme-color-btn').click(function (e) {
e.preventDefault();
var themeColor = $('#ThemeColor').val();
$.ajax({
url: '/Manage/ChangeThemeColor/' + themeColor,
type: "POST",
//dataType: "text",
data: {"themeColor": themeColor}, //.serialize(),
beforeSend: function () {
$('#apply-theme-color-btn').toggleClass('active');
},
success: function (data, textStatus, jqXHR) {
if (data.IsValid) {
console.log('Success');
}
else {
console.log(data);
}
},
error: function (jqXHR, textStatus, errorThrown) {
console.log('Error');
},
complete: function (jqXHR, textStatus) {
$('#apply-theme-color-btn').toggleClass('active');
}
});
});
控制器:
[HttpPost]
[Route("Manage/ChangeThemeColor/{themeColor:string}")]
public ActionResult ChangeThemeColor(string themeColor, IndexViewModel model) {
if (!ModelState.IsValid) {
var result = Json(new { IsValid = false, model = model, errors = ModelState.Values.Where(i => i.Errors.Count > 0) });
return result;
}
else {
//Do some different stuff
}
}
型号:
...
[Required]
[StringLength(7, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 7)]
public string ThemeColor { get; set; }
500 (Internal Server Error)
表示您在控制器方法中抛出异常,在您的情况下是评论中指出的循环引用异常。
要return无效属性的错误集合,请使用
errors = ModelState.Keys.Where(k => ModelState[k].Errors.Count > 0)
.Select(k => new { propertyName = k, errorMessage = ModelState[k].Errors[0].ErrorMessage })
这将 return 属性 名称和所有无效 属性 值的相关错误消息。
旁注:
url: '/Manage/ChangeThemeColor/' + themeColor,
应该只是
url: '/Manage/ChangeThemeColor',
因为你已经通过了
themeColor
在 data:
选项中(或者更好
@Url.Action("ChangeThemeColor", "Manage")',
)
- 由于
IndexViewModel
包含属性ThemeColor
,所以没有
在你的方法中需要参数,它应该只是 public
ActionResult ChangeThemeColor(IndexViewModel model)
- 无需将相同的模型发回给客户
客户端刚刚发送到控制器(从中删除
model = model"
return Json()
语句。
我有一个 ajax post 调用控制器操作并传递用户(我)输入的参数。
我正在使用数据注释来验证控制器操作中的模型。如果我输入无效值(或没有值)并且 运行 ajax:
- 调用控制器动作
- 发现模型无效(符合预期)
- 变量"result"定义如预期,包含模型、错误等
问题: return 似乎被忽略,响应为 500(内部服务器错误)。
此时我可以将状态代码设置为 200 来处理成功回调中的错误,但我无法用这个(在控制器操作中)覆盖它:
HttpContext.Response.TrySkipIisCustomErrors = true;
HttpContext.Response.StatusCode = (int)System.Net.HttpStatusCode.OK;
和这个(在 web.config 中):
<httpErrors errorMode="Custom" existingResponse="PassThrough"/>
如果我可以从中检索模型的错误,我也可以return将一个对象连接到错误回调,但从我所读的内容来看,这似乎是不可能的。
我搜索了那么多 post 和博客,这些似乎只适用于找到我不太能应用(技术上或概念上)的相同少数解决方案。
问题: 如何在传递给控制器的参数上保留数据注释并强制执行包含模型错误的某种对象的 return?
Ajax:
$('#apply-theme-color-btn').click(function (e) {
e.preventDefault();
var themeColor = $('#ThemeColor').val();
$.ajax({
url: '/Manage/ChangeThemeColor/' + themeColor,
type: "POST",
//dataType: "text",
data: {"themeColor": themeColor}, //.serialize(),
beforeSend: function () {
$('#apply-theme-color-btn').toggleClass('active');
},
success: function (data, textStatus, jqXHR) {
if (data.IsValid) {
console.log('Success');
}
else {
console.log(data);
}
},
error: function (jqXHR, textStatus, errorThrown) {
console.log('Error');
},
complete: function (jqXHR, textStatus) {
$('#apply-theme-color-btn').toggleClass('active');
}
});
});
控制器:
[HttpPost]
[Route("Manage/ChangeThemeColor/{themeColor:string}")]
public ActionResult ChangeThemeColor(string themeColor, IndexViewModel model) {
if (!ModelState.IsValid) {
var result = Json(new { IsValid = false, model = model, errors = ModelState.Values.Where(i => i.Errors.Count > 0) });
return result;
}
else {
//Do some different stuff
}
}
型号:
...
[Required]
[StringLength(7, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 7)]
public string ThemeColor { get; set; }
500 (Internal Server Error)
表示您在控制器方法中抛出异常,在您的情况下是评论中指出的循环引用异常。
要return无效属性的错误集合,请使用
errors = ModelState.Keys.Where(k => ModelState[k].Errors.Count > 0)
.Select(k => new { propertyName = k, errorMessage = ModelState[k].Errors[0].ErrorMessage })
这将 return 属性 名称和所有无效 属性 值的相关错误消息。
旁注:
url: '/Manage/ChangeThemeColor/' + themeColor,
应该只是url: '/Manage/ChangeThemeColor',
因为你已经通过了themeColor
在data:
选项中(或者更好@Url.Action("ChangeThemeColor", "Manage")',
)- 由于
IndexViewModel
包含属性ThemeColor
,所以没有 在你的方法中需要参数,它应该只是public ActionResult ChangeThemeColor(IndexViewModel model)
- 无需将相同的模型发回给客户
客户端刚刚发送到控制器(从中删除
model = model"
return Json()
语句。