- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在将js对象从我的视图发送到mvc控制器中的post操作
$.post("/home/someaction", { obj: myData }, function(data) {
alert(data);
});
[HttpPost]
public ActionResult someAction(MyModel obj)
{
if (!ModelState.IsValid)
{
ModelState.AddModelError("", "Error occured");
return View(obj);
}
...
}
最佳答案
您的someAction
是否是返回一个JsonResult
的Ajax方法。使用View()
方法返回ViewResult
,它是一个呈现的html页面。
现在,这是从操作方法返回Json
的常见要求。我的建议是使用JsonResult
操作类型。
https://msdn.microsoft.com/en-us/library/system.web.mvc.jsonresult%28v=vs.118%29.aspx
现在使用JsonResult
操作结果类型将确保您具有JSON结果,它不会以任何有意义的状态数据响应您的ajax请求。那取决于你。从AJAX角度再次处理ModelState
由您决定。这看似令人生畏,但实现Ajax处理程序和包装程序来处理此问题可能非常容易。
首先,我们需要了解我们将要处理什么类型的错误以及我们将如何处理它们。在我构建的大多数应用程序中,通常都将ActionResult
子类化,以允许我扩展对Ajax-Requests的响应方式。
让我们从请求生命周期开始
现在,典型的请求遵循这种生命周期:
发送到服务器的Ajax请求
服务器验证请求
401、30x未经授权的\重定向。表示无效的响应并重定向浏览器
调用Ajax方法:返回响应代码
200:响应正常
400:响应无效。 (确定可能不是正确的状态代码。但是,嘿!)
500:需要做更多的测试
在解释请求模型之前,响应代码400
是一个非常灰色的区域,因为它可能表示很多东西。您可能会考虑使用代码500
或501
,因为它们表明它们是服务器错误。但是,我通常喜欢以不同的方式处理这些错误,因为它们通常意味着更深层次的问题,应该以不同的方式进行处理。
现在,根据上述模型,我们完成了对服务器的请求,服务器将消化该请求并做出相应的响应。在典型的应用程序中,如果未授权用户,则ajax请求应返回401 Unauthorized
结果,如果请求的资源已移动,则应返回30x
响应。
一旦知道请求是有效的并且已通过身份验证,我们就可以继续通过action方法处理请求。如上所述,我喜欢(同意)对ActionResult
类进行子类化并相应地处理响应。现在,这里的计划(以及这完全是个人的行为)是将标准[结构化]对象返回给我们的Java脚本调用方法。子类化ActionResult
类型时,我们必须实现ExecuteResult
方法。这是最终返回给客户端的方法。我个人最喜欢的JSON
框架是Json.Net
,因此我们必须引用Package Json.Net
。
这是我们最初的AjaxResult
类:
public class AjaxResult : ActionResult
{
public object Data { get; set; }
public bool Completed { get; set; }
public string Message { get; set; }
public bool AllowGet { get; set; }
public override void ExecuteResult(ControllerContext context)
{
var result = new JsonResult
{
Data = new
{
Completed = this.Completed,
Message = this.Message,
Data = this.Data
}
};
result.JsonRequestBehavior = this.AllowGet ? JsonRequestBehavior.AllowGet : JsonRequestBehavior.DenyGet;
result.ExecuteResult(context);
}
}
AllowGet
只是告诉
JsonResult
是否接受get请求。但是,您应该已经适当地处理了。
[HttpPost]
public AjaxResult DoAjaxWork(AjaxModel model)
{
if (model == null)
{
return new AjaxResult
{
AllowGet = false,
Completed = false,
Message = "The model is null",
};
}
if (!ModelState.IsValid)
{
var error = this.ModelState.FirstOrDefault(x => x.Value.Errors.Count > 0).Value.Errors.First().ErrorMessage;
return new AjaxResult
{
AllowGet = false,
Message = error,
Completed = false
};
}
return new AjaxResult { Completed = true };
}
AjaxModel
类只有一个标记为
Required
的字段。在执行过程中(通常),我们检查
null
模型,然后检查
ModelState.IsValid
标志以确保模型有效。如果不是,我们通过将
Completed
标志设置为
false
来返回不完整的响应。然后,我们可以适当地在客户端上消化此情况。
function sendRequest() {
var requestData = {
myData: 'abcded'
}
$.ajax({
url: '@Url.Action("DoAjaxWork", "Default")',
data: JSON.stringify(requestData),
success: function (data) {
if (!data.Completed) {
alert(data.Message);
return;
}
alert('All Ok Boss')
},
error: function (jqXHR, textStatus, errorThrown) {
if (jqXHR.readyState == 0 || jqXHR.status == 0)
return; // it's not really an error
var errorStr = errorThrown;
switch (jqXHR.status) {
case 301:
case 302:
errorStr = "Redirected";
case 404:
errorStr = 'Not Found';
break;
case 500:
errorStr = 'There was an error completing the server request. The server operation failed.';
break;
case 401:
errorStr = errorThrown; //handle invalid request
break;
default:
errorStr = textStatus + ' ' + errorThrown;
break;
}
alert(errorStr);
}
});
}
200
,则单击
success
函数调用,然后让我们查看结构化对象,以确定请求是否实际上为
Completed
;否则,我们将显示返回的错误消息。否则,我们将继续完成的逻辑。
400
错误代码并消化模型状态。为此,我们需要对错误处理程序进行一些扩展。首先,让我们在ajax调用中进行这些假设。
Authentication
的最大问题。理想情况下,您将把我们在这里学到的知识抽象化到较低的水平,但是现在我们将在操作级别进行处理。我们需要使我们的
AjaxResponse
遵循我们设计的界面。到目前为止,我们的接口对每个请求都返回一个
200 Completed
响应。让我们用一个多于
200 Completed
的响应来响应。我们将保留
Completed
属性,但现在添加一个属性
StatusCode
(并使该属性
virtual
成为将来的证明)。
AjaxResult
类:
public partial class AjaxResult : ActionResult
{
public AjaxResult()
{
this.StatusCode = 200;
}
public virtual int StatusCode { get; set; }
public virtual object Data { get; set; }
public virtual bool Completed { get; set; }
public virtual string Message { get; set; }
public virtual bool AllowGet { get; set; }
public override void ExecuteResult(ControllerContext context)
{
if (context == null)
throw new ArgumentNullException("context");
if (!this.AllowGet && String.Equals(context.HttpContext.Request.HttpMethod, "GET", StringComparison.OrdinalIgnoreCase))
throw new InvalidOperationException("Ajax GET request not allowed.");
object responseData = new
{
Completed = this.Completed,
Message = this.Message,
Data = this.Data
};
HttpResponseBase response = context.HttpContext.Response;
response.Clear();
response.ContentType = "application/json";
response.StatusCode = this.StatusCode;
if (200 != response.StatusCode)
response.Write("{}"); //not valid.. you get no data!!!
else
response.Write(JsonConvert.SerializeObject(responseData));
}
}
public AjaxResult DoAjaxWork(AjaxModel model)
{
if (User == null) //do your own user validation tests
{
return new AjaxResult{ StatusCode = 401 };
}
//rest of our method
}
JsonResult
类型,但是现在有了我们自己的类型(尽管遵循.Net类型
https://aspnetwebstack.codeplex.com/SourceControl/latest#src/System.Web.Mvc/JsonResult.cs)。这个新班级的工作与上一班课完全相同,只是它响应不断变化的状态码。因此,众所周知,对于大多数AjaxRequest,只有
200
实际上是有效的状态代码(如果要缓存结果,请寻求其他建议)。
StatusCode
以外的
200
返回给客户端。现在,您可以在这里决定通过返回非200的
StatusCode
并在ajax错误处理程序中处理该错误或使用
CompletedFlag
来处理错误,来一般性地处理服务器验证错误和状态码。
ModelState
错误。可以采用它来满足您的需求。让我们向
AjaxResult
类添加一个方法。
public static AjaxResult Failed(ModelStateDictionary modelState, string titleMessage = "", bool allowGet = false)
{
StringBuilder errorBuilder = new StringBuilder();
if (!string.IsNullOrEmpty(titleMessage))
errorBuilder.AppendLine(titleMessage);
modelState.Where(x => x.Value.Errors != null && x.Value.Errors.Count > 0).SelectMany(x => x.Value.Errors).ToList().ForEach(e =>
{
string errorLine = null;
if (e.ErrorMessage != null)
errorLine = string.Concat("", e.ErrorMessage);
if (e.Exception != null)
errorLine = string.Concat(errorLine, "Exception:", e.Exception.Message);
errorBuilder.Append(errorLine);
});
return new AjaxResult
{
Completed = false,
StatusCode = 200, //Your call here.. 200 = check completed flag, else handle it in the error handler
AllowGet = false,
Data = null,
Message = errorBuilder.ToString()
};
}
ModelStateDictionary
发送到该类,它将结果标记为失败并适当地返回错误消息。现在,根据我们先前的Ajax请求模型,首先处理
Completed
标志,该标志允许应用程序立即就错误发出警报。只是为了好玩,我们添加了
titleMessage
变量,该变量允许我们在错误消息中添加
Header
。毕竟,我们原始的Ajax处理程序仍然可以承受这些更改。我们可以从动作中调用方法:
if (!ModelState.IsValid)
return AjaxResult.Failed(this.ModelState, "There was one or more errors", false);
success: function (data) {
if (!data.Completed) {
alert(data.Message);
return;
}
alert('All Ok Boss')
}
AjaxResult
类使您可以过滤除
200
以外的状态代码中的数据,并做出相应的响应。
400
状态代码并将
JavaScript
ajax调用包装到您自己的扩展中,并全局处理大多数错误和问题。
关于javascript - 在发送给 Controller 时使用js时,将modelstate错误返回到 View ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29892738/
我的 Controller 代码如下: [HttpPost] public ActionResult Create(ExampleViewModel model) { model.User.R
我正在开发 MVC5 代码优先应用程序。 在一个模型的 Edit() View 中,我包含了 [Create] 按钮,用于从 Edit() 中向其他模型添加新值> 查看并在 Edit() 上的 Dro
我的 MVC 应用程序中有一个问题,我不确定如何解决,或者我是否以错误的方式解决了这个问题。 我有一个 Controller / View ,它在带有复选框的网格中显示项目列表,当项目发布到我的 Co
我想知道是否可以自动将错误添加到 ModelState,以便检查我的 else 条件? if (ModelState.IsValid) { //Do something } else {
我有一个带有必需属性的模型对象 public class ApiPing { [Required] public DateTime ClientTime { get; set; }
如何测试 Controller.ViewData.ModelState?我宁愿在没有任何模拟框架的情况下这样做。 最佳答案 当然,如果您对数据使用存储库模式,则不必使用 Mock。 一些例子: htt
我正在使用 ASP.NET-MVC Core 2.1,我的代码中有这个 ViewModel 类 public class HomeViewModel { public
我有一个非常简单的 MVC 2 表单。它有两个下拉菜单,用户和角色。无论我选择什么,员工下拉列表都会通过验证,而角色下拉列表不会通过验证。尽管我计划实现一个,但没有默认的“空”选项,这就是为什么我需要
例如,有一个 Web Api 操作方法: public HttpMessageResponse Post(UserDto userDto) { if (!this.ModelState.IsV
如果我有以下模型: public class Model { public int ModelID { get; set; } public string Title { get; s
我的 DropDownLists 有一些问题,因为当我发布信息并且我的模型无效时,它返回“空”到页面触发错误,就像 this question . 我已经使用那里提出的解决方案,它解决了我的问题。无论
我的 DropDownLists 有一些问题,因为当我发布信息并且我的模型无效时,它返回“空”到页面触发错误,就像 this question . 我已经使用那里提出的解决方案,它解决了我的问题。无论
我想从 html 页面上的 dropdownList 获取参数并将其发送到我的 Controller ,创建新的模型对象,并将其插入数据库。 这是我的 Controller (创建 My_Model
我几乎总是想在回发时检查 ModelSate.IsValid 是否被调用。而且必须在每次回发开始时进行检查违反了 DRY 原则,有没有办法让它自动检查? 例子: [HttpPost("Register
我的模型类如下: public class PostInputViewModel { [Required] [MinLength(1)] [Ma
如何在 WEB Api .net 框架中将模型状态键设置为驼峰式大小写。 我使用 JsonProperty 特性将属性名称设置为驼峰式大小写。现在我希望 modelstate 与 json(驼峰式)相
所以,我有一个我很好奇的问题。我有一个 UserAccountViewModel,我正在重复使用它来创建帐户 View 和编辑帐户 View 。这样我就可以为我的代码使用一个 View 和一个 Vie
我正在编写一个 MVC 应用程序,其中包含一个对其进行验证的表单。 当我查询错误时,像这样: foreach (ModelState modelState in ViewData.ModelState
使用 MVC 时,当属性级别出现错误时,我们可以将错误添加到 ModelState但同样的错误也被添加到摘要中。我们如何避免显示它两次。 我只想在消息摘要中显示公共(public)错误,而在属性级别显
我有以下代码: public class EventController : ApiController { public IHttpActionResult Post(List Events
我是一名优秀的程序员,十分优秀!