4

My second day with ASP.NET MVC and my first request for code on SO (yep, taking a short cut).

I am looking for a way to create a filter that intercepts the current output from an Action and instead outputs JSON (I know of alternate approaches but this is to help me understand filters). I want to ignore any views associated with the action and just grab the ViewData["Output"], convert it to JSON and send it out the client. Blanks to fill:

TestController.cs:

[JSON]
public ActionResult Index()
{
 ViewData["Output"] = "This is my output";
 return View();
}

JSONFilter.cs:

public override void OnActionExecuting(ActionExecutingContext filterContext)
{
 /*
 * 1. How to override the View template and set it to null?
 * ViewResult { ViewName = "" } does not skip the view (/Test/Index)
 * 
 * 2. Get existing ViewData, convert to JSON and return with appropriate
 * custom headers
 */
}

Update: Community answers led to a fuller implementation for a filter for JSON/POX.

Paolo Bergantino
490k83 gold badges523 silver badges437 bronze badges
asked Mar 26, 2009 at 17:20

3 Answers 3

5

I would suggest that what you really want to do is use the Model rather than arbitrary ViewData elements and override OnActionExecuted rather than OnActionExecuting. That way you simply replace the result with your JsonResult before it gets executed and thus rendered to the browser.

public class JSONAttribute : ActionFilterAttribute
{
 ...
 public override void OnActionExecuted( ActionExecutedContext filterContext)
 {
 var result = new JsonResult();
 result.Data = ((ViewResult)filterContext.Result).Model;
 filterContext.Result = result;
 }
 ...
}
[JSON]public ActionResult Index()
{
 ViewData.Model = "This is my output";
 return View();
}
jpaugh
7,1645 gold badges46 silver badges94 bronze badges
answered Mar 26, 2009 at 18:03

3 Comments

Thanks. 1 line needs to be corrected to ((ViewResultBase)filterContext.Result)).ViewData.Model. However, the Index() action still shows the view associated with it (Views/Test/Index) instead of showing the JSON blob even though filterContext.Result has correct value.
Doing this in OnActionExecuted overrides the view and achieves what I was after.
Hmmm. I would have thought that replacing the result just before it was rendered would have been the proper time. I'll update my answer.
3

You haven't mentioned only returning the JSON conditionally, so if you want the action to return JSON every time, why not use:

public JsonResult Index()
{
 var model = new{ foo = "bar" };
 return Json(model);
}
answered Mar 26, 2009 at 18:35

1 Comment

The [JSON] attribute is being used to turn JSON on or off on certain actions but this is more of an exercise as I mentioned. In an actual implementation I would probably inspect the request http headers to determine response type.
0

maybe this post could help you the right way. The above post is also a method

answered Mar 26, 2009 at 18:34

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.