ASP.NET MVC: Как да създадете филтър за действие за извеждане на JSON?

Вторият ми ден с ASP.NET MVC и първата ми заявка за код на SO (да, по пряк път).

Търся начин да създам филтър, който прихваща текущия изход от действие и вместо това извежда JSON (знам за алтернативни подходи, но това е, за да ми помогне разбирам филтри). Искам да игнорирам всички изгледи, свързани с действието, и просто да взема ViewData["Output"], да го конвертирам в JSON и да го изпратя на клиента. Празни места за попълване:

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

Актуализация: Отговорите на общността доведоха до по-пълно изпълнение за филтър за JSON/POX.


person aleemb    schedule 26.03.2009    source източник


Отговори (3)


Бих предложил това, което наистина искате да направите, е да използвате модела, а не произволни ViewData елементи и да замените OnActionExecuted, а не OnActionExecuting. По този начин вие просто заменяте резултата с вашия JsonResult, преди да бъде изпълнен и по този начин изобразен в браузъра.

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();
}
person tvanfosson    schedule 26.03.2009
comment
Благодаря. 1 ред трябва да бъде коригиран на ((ViewResultBase)filterContext.Result)).ViewData.Model. Въпреки това, действието Index() все още показва изгледа, свързан с него (Views/Test/Index), вместо да показва JSON blob, въпреки че filterContext.Result има правилна стойност. - person aleemb; 26.03.2009
comment
Правенето на това в OnActionExecuted отменя изгледа и постига това, което преследвах. - person aleemb; 27.03.2009
comment
Хммм. Бих си помислил, че замяната на резултата точно преди да бъде изобразен би било подходящият момент. Ще актуализирам отговора си. - person tvanfosson; 27.03.2009

Не сте споменали само условно връщане на JSON, така че ако искате действието да връща JSON всеки път, защо не използвате:

public JsonResult Index()
{
    var model = new{ foo = "bar" };
    return Json(model);
}
person Troy    schedule 26.03.2009
comment
Атрибутът [JSON] се използва за включване или изключване на JSON при определени действия, но това е по-скоро упражнение, както споменах. При действително изпълнение вероятно бих проверил http заглавките на заявката, за да определя типа отговор. - person aleemb; 26.03.2009

може би това post може да ви помогне по правилния начин. Горният пост също е метод

person JSC    schedule 26.03.2009