代码改变世界

ASP.NET MVC 下自定义 ModelState 扩展类,响应给 AJAX

2018-12-20 15:36  音乐让我说  阅读(656)  评论(0编辑  收藏  举报

ModelStateExtensions.cs

using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;

namespace MvcSample.Extensions
{
    public static class ModelStateExtensions
    {
        private static string GetErrorMessage(ModelError error, ModelState modelState)
        {
            if (!string.IsNullOrEmpty(error.ErrorMessage))
            {
                return error.ErrorMessage;
            }
            if (modelState.Value == null)
            {
                return error.ErrorMessage;
            }
            var args = new object[] { modelState.Value.AttemptedValue };
            return string.Format("属性的值不合法=值 '{0}' 非法!", args);
        }

        public static object SerializeErrors(this ModelStateDictionary modelState)
        {
            return modelState.Where(entry => entry.Value.Errors.Any())
                .ToDictionary(entry => entry.Key, entry => SerializeModelState(entry.Value));
        }

        private static Dictionary<string, object> SerializeModelState(ModelState modelState)
        {
            var dictionary = new Dictionary<string, object>();
            dictionary["errors"] = modelState.Errors.Select(x => GetErrorMessage(x, modelState)).ToArray();
            return dictionary;
        }

        public static object ToDataSourceResult(this ModelStateDictionary modelState)
        {
            if (!modelState.IsValid)
            {
                return modelState.SerializeErrors();
            }
            return null;
        }
    }
}

 

控制器

        [HttpPost]
        public ActionResult ModifyProduct(ProductInfoModifyViewModel viewModel,
            [ModelBinder(typeof(CommaSeparatedModelBinder))] List<int> orderStatusIds = null)
        {
            if (!ModelState.IsValid)
            {
                return Json(new DataSourceResult { Errors = ModelState.SerializeErrors() });
            }
            ProductInfoService.TryModifyById(viewModel.ProductId, viewModel.NewYear);
            return Json(new { Success = true, Message = "保存成功" });
        }

DataSourceResult

    public class DataSourceResult
    {
        public object ExtraData { get; set; }

        public IEnumerable Data { get; set; }

        public object Errors { get; set; }

        public int Total { get; set; }
    }

 

前端(HTML)调用

        jQuery.ajax({
            type: "POST",
            url: "@Url.Action("ModifyProduct")",
            //data: { productId: productId, newYear: nowValue, orderStatusIds: "1,2,3,4", ProductName: " abc d e " }, //
            data: { productId: 0, ProductName: "" }, //
            success: function (data) {
                alert(data.Message);
                jObj.attr("old-value", nowValue);
            },
            error: function (xmlHttpRequest, textStatus, errorThrown) {
                alert(textStatus);
            }
        });

ProductInfoModifyViewModel.cs

using MvcSample.Extensions;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web;

namespace MvcSample.Models
{
    public class ProductInfoModifyViewModel : BaseSkyViewModel
    {
        [Required]
        [Range(1, int.MaxValue, ErrorMessage = "产品 ID 必须大于 0")]
        public int ProductId { get; set; }

        /// <summary>
        /// 假设有一个这个 Property
        /// </summary>
        [Display(Name = "产品名称")]
        [Required(ErrorMessage = "{0}不能为空!")]
        [StringLength(30, MinimumLength = 1, ErrorMessage = "{0}的长度必须在 {2} 和 {1} 之间")] //产品名称的长度必须在 1 和 30 之间
        public string ProductName { get; set; }


        public int NewYear { get; set; }
    }
}

 

运行效果:

{
    "ExtraData": null,
    "Data": null,
    "Errors": {
        "ProductId": {
            "errors": ["产品 ID 必须大于 0"]
        },
        "ProductName": {
            "errors": ["产品名称不能为空!"]
        }
    },
    "Total": 0
}

 

 

 

谢谢浏览!