c# - 如何覆盖基本 Controller 中 Json 辅助方法的行为

标签 c# json ajax asp.net-mvc jsonresult

我有以下问题:

Your application will respond to AJAX requests in JSON format. In order to maximize control over serialization, you will implement a custom ActionResult class.

You must override the behavior of the Json helper method in your base controller so that all JSON responses will use the custom result class. Which class should you inherit?

响应类型是JsonResult。在代码方面,我很难想象结构。当我读到问题中的“实现”时,我想到了一个接口(interface),所以这就是我想到的:

public class CustAction:ActionResult
{
  //max control over serialization
}
public interface ICustAction:CustAction
{
}

public controller MyController:ICustAction, JsonResult
{
   //override Json() method in here
}

上面的代码是否适用于上面的问题?

最佳答案

您可以覆盖 JsonResult,并返回自定义 JsonResult。 例如,

StandardJsonResult

public class StandardJsonResult : JsonResult
{
    public IList<string> ErrorMessages { get; private set; }

    public StandardJsonResult()
    {
        ErrorMessages = new List<string>();
    }

    public void AddError(string errorMessage)
    {
        ErrorMessages.Add(errorMessage);
    }

    public override void ExecuteResult(ControllerContext context)
    {
        if (context == null)
        {
            throw new ArgumentNullException("context");
        }

        /* If you do not want to serve JSON on HttpGet, uncomment this. */
        /*if (this.JsonRequestBehavior == JsonRequestBehavior.DenyGet &&
            string.Equals(context.HttpContext.Request.HttpMethod, "GET", StringComparison.OrdinalIgnoreCase))
        {
            throw new InvalidOperationException("GET access is not allowed. Change the JsonRequestBehavior if you need GET access.");
        }*/

        var response = context.HttpContext.Response;
        response.ContentType = string.IsNullOrEmpty(ContentType) ? "application/json" : ContentType;

        if (ContentEncoding != null)
        {
            response.ContentEncoding = ContentEncoding;
        }

        SerializeData(response);
    }

    protected virtual void SerializeData(HttpResponseBase response)
    {
        if (ErrorMessages.Any())
        {
            var originalData = Data;
            Data = new
            {
                Success = false,
                OriginalData = originalData,
                ErrorMessage = string.Join("\n", ErrorMessages),
                ErrorMessages = ErrorMessages.ToArray()
            };

            response.StatusCode = 400;
        }

        var settings = new JsonSerializerSettings
        {
            ContractResolver = new CamelCasePropertyNamesContractResolver(),
            Converters = new JsonConverter[]
            {
                new StringEnumConverter(),
            },
        };

        response.Write(JsonConvert.SerializeObject(Data, settings));
    }
}

public class StandardJsonResult<T> : StandardJsonResult
{
    public new T Data
    {
        get { return (T)base.Data; }
        set { base.Data = value; }
    }
}

基础 Controller

public abstract class BaseController : Controller
{
    protected StandardJsonResult JsonValidationError()
    {
        var result = new StandardJsonResult();

        foreach (var validationError in ModelState.Values.SelectMany(v => v.Errors))
        {
            result.AddError(validationError.ErrorMessage);
        }
        return result;
    }

    protected StandardJsonResult JsonError(string errorMessage)
    {
        var result = new StandardJsonResult();

        result.AddError(errorMessage);

        return result;
    }

    protected StandardJsonResult<T> JsonSuccess<T>(T data)
    {
        return new StandardJsonResult<T> { Data = data };
    }
}

用法

public class HomeController : BaseController
{
    public ActionResult Index()
    {
        return JsonResult(null, JsonRequestBehavior.AllowGet)

        // Uncomment each segment to test those feature.

        /* --- JsonValidationError Result ---
            {
                "success": false,
                "originalData": null,
                "errorMessage": "Model state error test 1.\nModel state error test 2.",
                "errorMessages": ["Model state error test 1.", "Model state error test 2."]
            }
            */
        ModelState.AddModelError("", "Model state error test 1.");
        ModelState.AddModelError("", "Model state error test 2.");
        return JsonValidationError();

        /* --- JsonError Result ---
            {
                "success": false,
                "originalData": null,
                "errorMessage": "Json error Test.",
                "errorMessages": ["Json error Test."]
            }
        */
        //return JsonError("Json error Test.");

        /* --- JsonSuccess Result ---
            {
                "firstName": "John",
                "lastName": "Doe"
            }
        */
        // return JsonSuccess(new { FirstName = "John", LastName = "Doe"});
    }
}

来源:Building Strongly-typed AngularJS Apps with ASP.NET MVC 5 by Matt Honeycutt

关于c# - 如何覆盖基本 Controller 中 Json 辅助方法的行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41918192/

相关文章:

c# - 是否有与 Apache Hadoop 等效的 .NET?

c# - 将 C# 单元测试名称转换为英文(testdox 样式)

C#使用按钮从DataGridView中的列表中删除元素仅工作一次

java - 序列化和反序列化过程中 JSON 属性的不同名称

javascript - jQuery-File-Upload - 仅显示以特定文件名开头的文件

c# - 是否可以创建具有通用事件的类?

json - ABAP 中用于转换为 Odata 原始类型的帮助程序类

PHP : Construction of Multidimensional Array to JSON

ajax - HTML如何在Ext.js中自动完成输入标签的标记?

javascript - jquery:合并 XML 文档