【问题标题】:ASP.NET MVC - JSON.NET extension method for controllerASP.NET MVC - 控制器的 JSON.NET 扩展方法
【发布时间】:2014-08-29 21:58:47
【问题描述】:

我刚刚将 JSON.NET 添加到我的项目中,我想创建一个名为 JsonNet 的扩展方法,它的行为方式与 Json 方法相同,但改用 JSON.NET。

我这里有一个使用 JSON.NET 扩展 JsonResult 的类:

public class JsonNetResult : JsonResult {
    public override void ExecuteResult(ControllerContext context) {
        if (context == null)
            throw new ArgumentNullException("context");

        var response = context.HttpContext.Response;

        response.ContentType = !String.IsNullOrEmpty(ContentType)
            ? ContentType
            : "application/json";

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

        var serializedObject = JsonConvert.SerializeObject(Data, Formatting.Indented);
        response.Write(serializedObject);
    }
}

在 ExecuteResult 方法下,我尝试添加这些:

public static JsonNetResult JsonNet(this Controller controller, object data) {
    var result = new JsonNetResult();
    result.Data = data;
    return result;
}

public static JsonNetResult JsonNet(this Controller controller, object data, JsonRequestBehavior behavior) {
    var result = new JsonNetResult();
    result.Data = data;
    result.JsonRequestBehavior = behavior;
    return result;
}

然后我有我的控制器:

public class SomethingController : Controller {
    public ActionResult SomeAction() {
        object data = SomeClass.GetData();
        return JsonNet(data, JsonRequestBehavior.AllowGet);
    }
}

而且编译器找不到 JsonNet 方法。即使我尝试这样做:

return ((Controller)this).JsonNet(data, JsonRequestBehavior.AllowGet);

还是不行。

如果我将 JsonNet 中的代码复制到 SomeAction 中,它工作得很好,所以我知道SomethingController 可以看到 JsonNetResult。

如果有帮助,这两个类位于不同的命名空间中。

【问题讨论】:

  • 显而易见的问题是您是否添加了正确的 using 语句。如果你写 Namespace.Class.JsonNet(this, data, JsonRequestBehavior.AllowGet) 会发生什么

标签: c# asp.net-mvc json json.net extension-methods


【解决方案1】:

这是我现在使用的一个,它还为我从中提取一些源代码的页面提供了 cmets。不过我自己做了一些调整,包括扩展方法。

如上所述,您需要将适当的 using 命名空间添加到您的控制器中。

我只是使用return this.JsonNet(data) 调用它。我只是允许自定义格式的覆盖,还有一个是因为我遇到了要求内容类型为“纯/文本”的 JS 插件。

//http://james.newtonking.com/archive/2008/10/16/asp-net-mvc-and-json-net.aspx
public class JsonNetResult : ActionResult
{
    public Encoding ContentEncoding { get; set; }
    public string ContentType { get; set; }
    public object Data { get; set; }

    public JsonSerializerSettings SerializerSettings { get; set; }
    public Formatting Formatting { get; set; }

    public JsonNetResult()
    {
        SerializerSettings = new JsonSerializerSettings
            {
                //http://odetocode.com/blogs/scott/archive/2013/03/25/asp-net-webapi-tip-3-camelcasing-json.aspx
                #if DEBUG
                Formatting = Formatting.Indented, //Makes the outputted Json for structures for easier reading by a human, only needed in debug
                #endif
                ContractResolver = new CamelCasePropertyNamesContractResolver() //Makes the default for properties outputted by Json to use camelCaps
            };
    }

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

        HttpResponseBase response = context.HttpContext.Response;

        response.ContentType = !string.IsNullOrEmpty(ContentType)
                                   ? ContentType
                                   : "application/json";

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

        if (Data != null)
        {
            JsonTextWriter writer = new JsonTextWriter(response.Output) {Formatting = Formatting};

            JsonSerializer serializer = JsonSerializer.Create(SerializerSettings);
            serializer.Serialize(writer, Data);

            writer.Flush();
        }
    }
}

public static class JsonNetExtenionMethods
{
    public static ActionResult JsonNet(this Controller controller, object data)
    {
        return new JsonNetResult() {Data = data};
    }

    public static ActionResult JsonNet(this Controller controller, object data, string contentType)
    {
        return new JsonNetResult() { Data = data, ContentType = contentType };
    }

    public static ActionResult JsonNet(this Controller controller, object data, Formatting formatting)
    {
        return new JsonNetResult() {Data = data, Formatting = formatting};
    }
}

【讨论】:

    【解决方案2】:

    编译器不会找到扩展方法,除非它们在静态类中。尝试将您的 JsonNet 方法放在他们自己的静态类中,例如JsonNetExtensions。还要确保你的扩展类与你的控制器在同一个命名空间中,或者你的控制器在顶部有一个 using 声明,带有扩展类的命名空间。

    【讨论】:

    • 扩展方法不会编译,除非它们在静态类中。这些方法要么在静态类中,要么他没有告诉我们它们不能编译的事实:)
    • @Stilgar 根据问题,他在非静态 JsonNetResult 类中有扩展方法;我猜他只是还没有尝试按照这种安排来构建项目。在您实际尝试构建项目之前,Visual Studio 不会将其标记为错误(即带有红色波浪下划线)。
    • 我明白了!我也考虑过静态类,但决定他会尝试编译:)
    猜你喜欢
    • 1970-01-01
    • 2013-09-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多