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?
The reason to this is that all Html.Action
invocations are executed directly. Something like:
- Index is called
- View result is executed
- Hello action is executed, set's ContextType
- Index view result is returned
- Browser displays the page
You got two options:
- Break out the logic which generates "Hello world!" into a regular C# class and invoke it directly in the Index controller action
- 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);
}
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);
}
}
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