简体   繁体   中英

ASP.NET MVC - JSON.NET extension method for controller

I just added JSON.NET to my project, and I would like to create an extension method called JsonNet that behaves the same way as the Json method, but uses JSON.NET instead.

I have a class here that extends JsonResult using JSON.NET:

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

Underneath the ExecuteResult method, I tried to add these:

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

And then I have my controller:

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

And the compiler cannot find the JsonNet method. Even when I try this:

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

it still doesn't work.

If I copy the code in JsonNet into SomeAction, it works just fine, so I know SomethingController can see JsonNetResult.

If it helps, the two classes are in separate namespaces.

This is the one I use now, it also has comments for the pages where I pulled some of the source from. I've made tweaks of my own though, including the extension methods.

And as mentioned, you need to have the appropriate using namespace added to your controller.

I just call it using return this.JsonNet(data) . The overrides I just have for allowing customization of the Formatting, and one because I ran into JS plugin that required the content type to be 'plain/text'.

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

Extension methods will not be found by the compiler unless they are in a static class. Try putting your JsonNet methods in their own static class called eg JsonNetExtensions . Also make sure that your extensions class is either in the same namespace as your controllers, or your controllers have a using statement at the top with the namespace of the extensions class.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM