【问题标题】:How to override behavior of Json helper method in base controller如何在基本控制器中覆盖 Json 辅助方法的行为
【发布时间】:2017-01-29 06:13:12
【问题描述】:

我有以下问题:

您的应用程序将以 JSON 格式响应 AJAX 请求。在 为了最大限度地控制序列化,您将实现一个 自定义 ActionResult 类。

您必须在您的基础中覆盖 Json 辅助方法的行为 控制器,以便所有 JSON 响应都将使用自定义结果 班级。你应该继承哪个类?

响应类型是JsonResult。就代码而言,我很难将结构可视化。当我在问题中阅读“implement”时,我想到了一个interface,所以我想到了这个:

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

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

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

【问题讨论】:

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


【解决方案1】:

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

标准JsonResult

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; }
    }
}

基本控制器

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

【讨论】:

    【解决方案2】:
    public class customJsonResult : JsonResult
    {
      //max control over serialization
     }
    
    //in the base controller override the Controller.Json helper method:
    protected internal override JsonResult Json(object data, string contentType, Encoding contentEncoding, JsonRequestBehavior behavior)
    {
        return new customJsonResult {
            Data = data,
            ContentType = contentType,
            ContentEncoding = contentEncoding,
            JsonRequestBehavior = behavior
        };
    }
    

    【讨论】:

    • 请考虑为您的答案添加一些解释。
    猜你喜欢
    • 2020-08-22
    • 2012-08-12
    • 1970-01-01
    • 2021-11-03
    • 2011-02-05
    • 2011-08-03
    • 2021-05-20
    • 1970-01-01
    • 2013-12-15
    相关资源
    最近更新 更多