简体   繁体   English

根据参数从任何ASP.NET MVC控制器操作返回JSON

[英]Return JSON from any ASP.NET MVC controller action based on a parameter

During development I often write my controller methods like this so I can ensure the contents of the model are properly populated and to aid in development of the view. 在开发过程中,我经常这样编写控制器方法,以便确保模型的内容正确填充并有助于视图的开发。

public ActionResult SomeMethod(int id, bool asJson = false)
{
    var model = SomeBackendService.GetModel(id);
    if(asJson)
        return Json(model, JsonRequestBehavior.AllowGet);
    return View(model);
}

I change them once the view development is done, but then sometimes I find myself wishing I could get the results as JSON later on. 一旦视图开发完成,我就更改了它们,但是有时我发现自己希望以后可以将结果转换为JSON。

Ideally, I'd like to set a Web.config key that would allow the the controller method to be requested as JSON without recoding each method for each controller. 理想情况下,我想设置一个Web.config密钥,该密钥允许将控制器方法请求为JSON,而无需为每个控制器重新编码每个方法。 I'd like the following method to return the model as JSON when requested with a certain querystring parameter. 我希望以下方法在使用特定的querystring参数进行请求时以JSON形式返回模型。

public ActionResult SomeMethod(int id)
{
    var model = SomeBackendService.GetModel(id);
    return View(model);
}

I'm guessing the road I need to travel down is to implement my own view engine, but I'm not sure that is correct. 我猜我需要走的路是实现自己的视图引擎,但是我不确定那是正确的。

Actually, I figured out how to do this using a custom DisplayModeProvider. 实际上,我想出了如何使用自定义DisplayModeProvider进行此操作。

It occurred to me that I can just all I really need to do is to use a view that will render the JSON. 我突然想到,我真正需要做的就是使用将呈现JSON的视图。 So I created a custom DisplayProvider to override the TransformPath method: 因此,我创建了一个自定义DisplayProvider来覆盖TransformPath方法:

public class JsonOnlyDisplayProvider : DefaultDisplayMode
{
    public JsonOnlyDisplayProvider(string suffix) : base(suffix) { }        

    protected override string TransformPath(string virtualPath, string suffix)
    {
        return "~/Views/Shared/JsonOnly.cshtml";
    }
}

Then I modified the Application_Start method in Global.asax to insert the new provider with a ContextCondition that evaluates the AppSetting and querystring parameter. 然后,我修改了Global.asax中的Application_Start方法,以使用ContextCondition插入新的提供程序来评估AppSetting和querystring参数。

protected void Application_Start()
{        
    DisplayModeProvider.Instance.Modes.Insert(0, 
        new JsonOnlyDisplayProvider(DisplayModeProvider.DefaultDisplayModeId)
    {
        ContextCondition = context => 
            (context.Request.QueryString["asJson"] == "true" && 
             !string.IsNullOrEmpty(ConfigurationManager.AppSettings["AllowJson"]) && 
             ConfigurationManager.AppSettings["AllowJson"] == "true")
    });
}

The last step was to create the generic view that would spew out the JSON. 最后一步是创建将生成JSON的通用视图。 (Granted, this approach does not add the appropriate headers...I'm open to suggestions on how to get that sorted) (当然,这种方法不会添加适当的标题...我愿意接受有关如何进行排序的建议)

JsonOnly.cshtml JsonOnly.cshtml

@{
    Layout = null;
    if (Model != null)
    {
        @Html.Raw(Json.Encode(Model))
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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