Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP.NET MVC: Should Controllers called by AJAX return JSON or rendered html?

Tags:

I am having trouble deciding if a controller action, which is called by AJAX, should return a partial view, or the "raw" JSON.

Returning a partial view, with rendered HTML makes it easier for the javascript to simply update the current DOM with the returned HTML. However, it does limit what javascript client consuming the webservice can do with the returned HTML.

On the other-hand, having the controller action return JSON would require the javascript making the call to "manually" create the markup based on the JSON that is returned.

So as usual, each approach has it's benefits and weakness. Are there any other pros/cons for each approach?

like image 897
Cloud SME Avatar asked May 27 '09 18:05

Cloud SME


People also ask

How display JSON data in HTML using Ajax in asp net?

Create target "JSON object Mapper" object class file according to the business requirements. Create a "Controllers\HomeController. cs" file with default Index method and GetData(...) method with string type input query parameters for Ajax call with following lines of code i.e.

Why We Need Ajax call in MVC?

It is a client-side script that communicates to and from a server/database without the need for a postback or a complete page refresh. The Ajax speeds up response time. In other words, Ajax is the method of exchanging data with a server, and updating parts of a web page, without reloading the entire page.

What is return JSON in MVC?

What is JsonResult ? JsonResult is one of the type of MVC action result type which returns the data back to the view or the browser in the form of JSON (JavaScript Object notation format).

How can we send data from controller view in MVC?

The other way of passing the data from Controller to View can be by passing an object of the model class to the View. Erase the code of ViewData and pass the object of model class in return view. Import the binding object of model class at the top of Index View and access the properties by @Model.


2 Answers

In my opinion, returning JSON and then letting the client side view sort it out can be messy because of the following limitations:

  1. No standard templating language for JavaScript. In the worst case scenario, you'll be tempted to concatenate strings to form the HTML that you require.
  2. No easy way to unit test the HTML generated by your concatenation code.
  3. Lack of IntelliSense for your JavaScript means that you're also prone to make more mistakes.

The way I've handled this is to return rendered HTML, BUT return this rendered HTML using a partial view instead. This gives you the best of both worlds. You've got Server-side templates as well as IntelliSense support.

Here's an example:

Here's my Ajax call, as you can see all it does is replace the html for my unordered list:

FilterRequests: function() {     $.post("/Request.aspx/GetFilteredRequests", { }, function(data) {         $('ul.requests').html(data);     }); }, 

Here's my action on my controller:

public ActionResult GetFilteredRequests(string filterJson) {     var requests = _requestDao.LoadAll();      return PartialView("FilteredRequests", requests); } 

Finally here is my partial view (there's no need to understand this, I'm just showing you how complex some rendering can get in a real world application. I'd dread doing this in JavaScript. You'll also notice that my partial view in turn calls other partial views as well.):

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<IEnumerable<Request>>" %> <%@ Import Namespace="Diangy.HelpDesk.Models.Lookups"%> <%@ Import Namespace="Diangy.HelpDesk.Models.Requests"%> <%@ Import Namespace="System.Web.Mvc.Html"%>  <% foreach (var request in ViewData.Model) %> <%{%>     <li class="request">         <h2>#<%= request.Id %>: <%= request.InitialInteraction().Description %></h2>         <p>from <%= request.Customer.FullName %> (<%= request.Customer.EmailAddress %>), <%= request.InitialInteraction().UsableTimeStamp %></p>          <h3>Custom Fields & Lookups</h3>         <div class="tabs">             <ul>             <li><a href="#customfields<%= request.Id %>">Custom Fields</a></li>             <% foreach (var lookupDefinition in (List<LookupDefinition>)ViewData["LookupDefinitions"]) %>             <%{%>             <li><a href="#<%= lookupDefinition.Name.ToLowerInvariant().Replace(" ", "") + request.Id %>"><%= lookupDefinition.Name %></a></li>             <%}%>         </ul>         <% Html.RenderPartial("CustomFields", request); %>     </div>      <% Html.RenderPartial("Discussion", request); %>     <% Html.RenderPartial("Attachment", request); %>     </li> <%}%> 
like image 165
Praveen Angyan Avatar answered Oct 20 '22 13:10

Praveen Angyan


If you are using the MVC paradigm, the controller should return data (JSON) and let the view sort it out for itself, just like its job is to find/adapt the data in the model and pass it on to the view on the server side.

You get browny points for

  • preserving separation of concerns between logic and UI

  • making your ajax actions testable (good luck testing the HTML returned from that action...)

It's a bit more complicated maybe, but it fits.

You can use client-templating systems such as what is now available in the MS Ajax Toolkit to help take some of the load and preserve the logic/rendering separation on the client side.

So I'd say JSON, definitely. But hey, YMMV as usual...

like image 28
Denis Troller Avatar answered Oct 20 '22 14:10

Denis Troller