calling @Html.Action for JsonResult changes my response type in parent template

落花浮王杯 提交于 2019-11-30 23:09:21

问题


I've got the following controller:

public class HelloController
{
    public ActionResult Index()
    {
        return View()
    }

    public ActionResult Hello()
    {
        return Json(new{ greeting = "hello, world!" }, JsonRequestBehavior.AllowGet);
    }
}

Then, inside Index.cshtml:

...html stuffs
<script type="text/javascript">
    alert("@Html.Action("Hello")");
</script>

What I'm finding is that, when going to this url in my browser, the response content type is application/json; charset=utf-8 which causes the browser to render the html as a string instead of as... a web page.

What's the best way to get around this?


回答1:


The reason to this is that all Html.Action invocations are executed directly. Something like:

  1. Index is called
  2. View result is executed
  3. Hello action is executed, set's ContextType
  4. Index view result is returned
  5. Browser displays the page

You got two options:

  1. Break out the logic which generates "Hello world!" into a regular C# class and invoke it directly in the Index controller action
  2. Load the Hello action through ajax and then display the alert.

Option 1

public class HelloController
{
    YourBusiness _yb;

    public HelloController(YourBusiness yb)
    {
        _yb = yb;
    } 
    public ActionResult Index()
    {
        return View(yb.GenerateHello())
    }

    // used for everything but Index
    public ActionResult Hello()
    {
        return Json(new{ greeting = yb.GenerateHello() }, JsonRequestBehavior.AllowGet);
    }
}

public class YourBusiness
{
    public string GenerateHello()
    {
        return "Hello wolrd!";
    }
}

Option 2

<script type="text/javascript">
    $.get('@Url.Action("Hello")', function(response) {
        alert(response.greeting);
    }
</script>

Side note

Internet Explorer is quite aggressive when it comes to caching. The JSON responses will be changed. I therefore recommend that you also specify no cache for the JSON action:

[OutputCache(Duration = 0, NoStore = true)]
public ActionResult Hello()
{
    return Json(new{ greeting = "hello, world!" }, JsonRequestBehavior.AllowGet);
}



回答2:


Just use the overload of Json(...) to set the correct content type.

public class HelloController
{
    public ActionResult Index()
    {
        return View()
    }

    public ActionResult Hello()
    {
        return Json(new{ greeting = "hello, world!" }, "text/html", JsonRequestBehavior.AllowGet);
    }
}



回答3:


If you return a JsonResult, via calling the Json() method, it won't return a web page. To return a page, you need to return a ViewResult, via calling the View method. Your method should have a corresponding view template

Check out this link or this one



来源:https://stackoverflow.com/questions/10543953/calling-html-action-for-jsonresult-changes-my-response-type-in-parent-template

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!