2009-03-26 4 views
4

ASP.NET MVCで私の2日目と私の最初のSOの要求がありました(ちょっとしたことです)。ASP.NET MVC:アクションフィルタを作成してJSONを出力する方法は?

アクションからの現在の出力を傍受し、代わりにJSONを出力するフィルタを作成する方法を探しています(私はalternate approachesを知っていますが、これはフィルタを理解するのに役立ちます)。私はアクションに関連するビューをすべて無視し、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 
    */ 
} 

更新:コミュニティの回答がfilter for JSON/POXのための充実した実装につながりました。

答えて

4

あなたが実際にやりたいことは、任意のViewData要素ではなくモデルを使用し、OnActionExecutingではなくOnActionExecutedを上書きすることです。そのようにすれば、結果が実行されてブラウザに表示される前に、結果を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(); 
} 
+0

感謝を。 1行を((ViewResultBase)filterContext.Result)に修正する必要があります。)ViewData.Model。ただし、filterContext.Resultが正しい値を持っていても、Index()アクションはJSON blobを表示するのではなく、関連するビュー(Views/Test/Index)を表示します。 – aleemb

+0

OnActionExecutedでこれを行うと、ビューがオーバーライドされ、後になったことが達成されます。 – aleemb

+0

Hmmm。私は、レンダリングされる直前の結果を置き換えることが適切な時期だったと思っていたでしょう。私は私の答えを更新します。 – tvanfosson

0

多分このpostが正しい方法を助けます。上記の記事はまた、あなたが唯一の条件付きでJSONを返す言及していない方法

3

あるので、あなたは、アクションはJSONを毎回返すようにしたい場合は、なぜ使用しない:

public JsonResult Index() 
{ 
    var model = new{ foo = "bar" }; 
    return Json(model); 
} 
+0

[JSON]属性は、特定のアクションでJSONをオンまたはオフにするために使用されていますが、これは私が言及したように多くの練習です。実際の実装では、おそらくレスポンスタイプを決定するためにリクエストのhttpヘッダを調べるでしょう。 – aleemb