[ajax] ASP.NET MVC controller actions that return JSON or partial html

I am trying to create controller actions which will return either JSON or partial html depending upon a parameter. What is the best way to get the result returned to an MVC page asynchronously?

This question is related to ajax asp.net-mvc json asp.net-ajax

The answer is


To answer the other half of the question, you can call:

return PartialView("viewname");

when you want to return partial HTML. You'll just have to find some way to decide whether the request wants JSON or HTML, perhaps based on a URL part/parameter.


Alternative solution with incoding framework

Action return json

Controller

    [HttpGet]
    public ActionResult SomeActionMethod()
    {
        return IncJson(new SomeVm(){Id = 1,Name ="Inc"});
    }

Razor page

@using (var template = Html.Incoding().ScriptTemplate<SomeVm>("tmplId"))
{
    using (var each = template.ForEach())
    {
        <span> Id: @each.For(r=>r.Id) Name: @each.For(r=>r.Name)</span>
    }
}

@(Html.When(JqueryBind.InitIncoding)
  .Do()
  .AjaxGet(Url.Action("SomeActionMethod","SomeContoller"))
  .OnSuccess(dsl => dsl.Self().Core()
                              .Insert
                              .WithTemplate(Selector.Jquery.Id("tmplId"))
                              .Html())
  .AsHtmlAttributes()
  .ToDiv())

Action return html

Controller

    [HttpGet]
    public ActionResult SomeActionMethod()
    {
        return IncView();
    }

Razor page

@(Html.When(JqueryBind.InitIncoding)
  .Do()
  .AjaxGet(Url.Action("SomeActionMethod","SomeContoller"))
  .OnSuccess(dsl => dsl.Self().Core().Insert.Html())
  .AsHtmlAttributes()
  .ToDiv())

Another nice way to deal with JSON data is using the JQuery getJSON function. You can call the

public ActionResult SomeActionMethod(int id) 
{ 
    return Json(new {foo="bar", baz="Blech"});
}

Method from the jquery getJSON method by simply...

$.getJSON("../SomeActionMethod", { id: someId },
    function(data) {
        alert(data.foo);
        alert(data.baz);
    }
);

To answer the other half of the question, you can call:

return PartialView("viewname");

when you want to return partial HTML. You'll just have to find some way to decide whether the request wants JSON or HTML, perhaps based on a URL part/parameter.


I think you should consider the AcceptTypes of the request. I am using it in my current project to return the correct content type as follows.

Your action on the controller can test it as on the request object

if (Request.AcceptTypes.Contains("text/html")) {
   return View();
}
else if (Request.AcceptTypes.Contains("application/json"))
{
   return Json( new { id=1, value="new" } );
}
else if (Request.AcceptTypes.Contains("application/xml") || 
         Request.AcceptTypes.Contains("text/xml"))
{
   //
}

You can then implement the aspx of the view to cater for the partial xhtml response case.

Then in jQuery you can fetch it passing the type parameter as json:

$.get(url, null, function(data, textStatus) {
        console.log('got %o with status %s', data, textStatus);
        }, "json"); // or xml, html, script, json, jsonp or text

Hope this helps James


For folks who have upgraded to MVC 3 here is a neat way Using MVC3 and Json


PartialViewResult and JSONReuslt inherit from the base class ActionResult. so if return type is decided dynamically declare method output as ActionResult.

public ActionResult DynamicReturnType(string parameter)
        {
            if (parameter == "JSON")
                return Json("<JSON>", JsonRequestBehavior.AllowGet);
            else if (parameter == "PartialView")
                return PartialView("<ViewName>");
            else
                return null;


        }

Another nice way to deal with JSON data is using the JQuery getJSON function. You can call the

public ActionResult SomeActionMethod(int id) 
{ 
    return Json(new {foo="bar", baz="Blech"});
}

Method from the jquery getJSON method by simply...

$.getJSON("../SomeActionMethod", { id: someId },
    function(data) {
        alert(data.foo);
        alert(data.baz);
    }
);

You may want to take a look at this very helpful article which covers this very nicely!

Just thought it might help people searching for a good solution to this problem.

http://weblogs.asp.net/rashid/archive/2009/04/15/adaptive-rendering-in-asp-net-mvc.aspx


I found a couple of issues implementing MVC ajax GET calls with JQuery that caused me headaches so sharing solutions here.

  1. Make sure to include the data type "json" in the ajax call. This will automatically parse the returned JSON object for you (given the server returns valid json).
  2. Include the JsonRequestBehavior.AllowGet; without this MVC was returning a HTTP 500 error (with dataType: json specified on the client).
  3. Add cache: false to the $.ajax call, otherwise you will ultimately get HTTP 304 responses (instead of HTTP 200 responses) and the server will not process your request.
  4. Finally, the json is case sensitive, so the casing of the elements needs to match on the server side and client side.

Sample JQuery:

$.ajax({
  type: 'get',
  dataType: 'json',
  cache: false,
  url: '/MyController/MyMethod',
  data: { keyid: 1, newval: 10 },
  success: function (response, textStatus, jqXHR) {
    alert(parseInt(response.oldval) + ' changed to ' + newval);                                    
  },
  error: function(jqXHR, textStatus, errorThrown) {
    alert('Error - ' + errorThrown);
  }
});

Sample MVC code:

[HttpGet]
public ActionResult MyMethod(int keyid, int newval)
{
  var oldval = 0;

  using (var db = new MyContext())
  {
    var dbRecord = db.MyTable.Where(t => t.keyid == keyid).FirstOrDefault();

    if (dbRecord != null)
    {
      oldval = dbRecord.TheValue;
      dbRecord.TheValue = newval;
      db.SaveChanges();
    }
  }

    return Json(new { success = true, oldval = oldval},
                JsonRequestBehavior.AllowGet);
}

Another nice way to deal with JSON data is using the JQuery getJSON function. You can call the

public ActionResult SomeActionMethod(int id) 
{ 
    return Json(new {foo="bar", baz="Blech"});
}

Method from the jquery getJSON method by simply...

$.getJSON("../SomeActionMethod", { id: someId },
    function(data) {
        alert(data.foo);
        alert(data.baz);
    }
);

For folks who have upgraded to MVC 3 here is a neat way Using MVC3 and Json


Alternative solution with incoding framework

Action return json

Controller

    [HttpGet]
    public ActionResult SomeActionMethod()
    {
        return IncJson(new SomeVm(){Id = 1,Name ="Inc"});
    }

Razor page

@using (var template = Html.Incoding().ScriptTemplate<SomeVm>("tmplId"))
{
    using (var each = template.ForEach())
    {
        <span> Id: @each.For(r=>r.Id) Name: @each.For(r=>r.Name)</span>
    }
}

@(Html.When(JqueryBind.InitIncoding)
  .Do()
  .AjaxGet(Url.Action("SomeActionMethod","SomeContoller"))
  .OnSuccess(dsl => dsl.Self().Core()
                              .Insert
                              .WithTemplate(Selector.Jquery.Id("tmplId"))
                              .Html())
  .AsHtmlAttributes()
  .ToDiv())

Action return html

Controller

    [HttpGet]
    public ActionResult SomeActionMethod()
    {
        return IncView();
    }

Razor page

@(Html.When(JqueryBind.InitIncoding)
  .Do()
  .AjaxGet(Url.Action("SomeActionMethod","SomeContoller"))
  .OnSuccess(dsl => dsl.Self().Core().Insert.Html())
  .AsHtmlAttributes()
  .ToDiv())

Flexible approach to produce different outputs based on the request

public class AuctionsController : Controller
{
  public ActionResult Auction(long id)
  {
    var db = new DataContext();
    var auction = db.Auctions.Find(id);

    // Respond to AJAX requests
    if (Request.IsAjaxRequest())
      return PartialView("Auction", auction);

    // Respond to JSON requests
    if (Request.IsJsonRequest())
      return Json(auction);

    // Default to a "normal" view with layout
    return View("Auction", auction);
  }
}

The Request.IsAjaxRequest() method is quite simple: it merely checks the HTTP headers for the incoming request to see if the value of the X-Requested-With header is XMLHttpRequest, which is automatically appended by most browsers and AJAX frameworks.

Custom extension method to check whether the request is for json or not so that we can call it from anywhere, just like the Request.IsAjaxRequest() extension method:

using System;
using System.Web;

public static class JsonRequestExtensions
{
  public static bool IsJsonRequest(this HttpRequestBase request)
  {
    return string.Equals(request["format"], "json");
  }
}

Source : https://www.safaribooksonline.com/library/view/programming-aspnet-mvc/9781449321932/ch06.html#_javascript_rendering


I think you should consider the AcceptTypes of the request. I am using it in my current project to return the correct content type as follows.

Your action on the controller can test it as on the request object

if (Request.AcceptTypes.Contains("text/html")) {
   return View();
}
else if (Request.AcceptTypes.Contains("application/json"))
{
   return Json( new { id=1, value="new" } );
}
else if (Request.AcceptTypes.Contains("application/xml") || 
         Request.AcceptTypes.Contains("text/xml"))
{
   //
}

You can then implement the aspx of the view to cater for the partial xhtml response case.

Then in jQuery you can fetch it passing the type parameter as json:

$.get(url, null, function(data, textStatus) {
        console.log('got %o with status %s', data, textStatus);
        }, "json"); // or xml, html, script, json, jsonp or text

Hope this helps James


To answer the other half of the question, you can call:

return PartialView("viewname");

when you want to return partial HTML. You'll just have to find some way to decide whether the request wants JSON or HTML, perhaps based on a URL part/parameter.


    public ActionResult GetExcelColumn()
    {            
            List<string> lstAppendColumn = new List<string>();
            lstAppendColumn.Add("First");
            lstAppendColumn.Add("Second");
            lstAppendColumn.Add("Third");
  return Json(new { lstAppendColumn = lstAppendColumn,  Status = "Success" }, JsonRequestBehavior.AllowGet);
            }
        }

PartialViewResult and JSONReuslt inherit from the base class ActionResult. so if return type is decided dynamically declare method output as ActionResult.

public ActionResult DynamicReturnType(string parameter)
        {
            if (parameter == "JSON")
                return Json("<JSON>", JsonRequestBehavior.AllowGet);
            else if (parameter == "PartialView")
                return PartialView("<ViewName>");
            else
                return null;


        }

I found a couple of issues implementing MVC ajax GET calls with JQuery that caused me headaches so sharing solutions here.

  1. Make sure to include the data type "json" in the ajax call. This will automatically parse the returned JSON object for you (given the server returns valid json).
  2. Include the JsonRequestBehavior.AllowGet; without this MVC was returning a HTTP 500 error (with dataType: json specified on the client).
  3. Add cache: false to the $.ajax call, otherwise you will ultimately get HTTP 304 responses (instead of HTTP 200 responses) and the server will not process your request.
  4. Finally, the json is case sensitive, so the casing of the elements needs to match on the server side and client side.

Sample JQuery:

$.ajax({
  type: 'get',
  dataType: 'json',
  cache: false,
  url: '/MyController/MyMethod',
  data: { keyid: 1, newval: 10 },
  success: function (response, textStatus, jqXHR) {
    alert(parseInt(response.oldval) + ' changed to ' + newval);                                    
  },
  error: function(jqXHR, textStatus, errorThrown) {
    alert('Error - ' + errorThrown);
  }
});

Sample MVC code:

[HttpGet]
public ActionResult MyMethod(int keyid, int newval)
{
  var oldval = 0;

  using (var db = new MyContext())
  {
    var dbRecord = db.MyTable.Where(t => t.keyid == keyid).FirstOrDefault();

    if (dbRecord != null)
    {
      oldval = dbRecord.TheValue;
      dbRecord.TheValue = newval;
      db.SaveChanges();
    }
  }

    return Json(new { success = true, oldval = oldval},
                JsonRequestBehavior.AllowGet);
}

Another nice way to deal with JSON data is using the JQuery getJSON function. You can call the

public ActionResult SomeActionMethod(int id) 
{ 
    return Json(new {foo="bar", baz="Blech"});
}

Method from the jquery getJSON method by simply...

$.getJSON("../SomeActionMethod", { id: someId },
    function(data) {
        alert(data.foo);
        alert(data.baz);
    }
);

    public ActionResult GetExcelColumn()
    {            
            List<string> lstAppendColumn = new List<string>();
            lstAppendColumn.Add("First");
            lstAppendColumn.Add("Second");
            lstAppendColumn.Add("Third");
  return Json(new { lstAppendColumn = lstAppendColumn,  Status = "Success" }, JsonRequestBehavior.AllowGet);
            }
        }

Flexible approach to produce different outputs based on the request

public class AuctionsController : Controller
{
  public ActionResult Auction(long id)
  {
    var db = new DataContext();
    var auction = db.Auctions.Find(id);

    // Respond to AJAX requests
    if (Request.IsAjaxRequest())
      return PartialView("Auction", auction);

    // Respond to JSON requests
    if (Request.IsJsonRequest())
      return Json(auction);

    // Default to a "normal" view with layout
    return View("Auction", auction);
  }
}

The Request.IsAjaxRequest() method is quite simple: it merely checks the HTTP headers for the incoming request to see if the value of the X-Requested-With header is XMLHttpRequest, which is automatically appended by most browsers and AJAX frameworks.

Custom extension method to check whether the request is for json or not so that we can call it from anywhere, just like the Request.IsAjaxRequest() extension method:

using System;
using System.Web;

public static class JsonRequestExtensions
{
  public static bool IsJsonRequest(this HttpRequestBase request)
  {
    return string.Equals(request["format"], "json");
  }
}

Source : https://www.safaribooksonline.com/library/view/programming-aspnet-mvc/9781449321932/ch06.html#_javascript_rendering


You may want to take a look at this very helpful article which covers this very nicely!

Just thought it might help people searching for a good solution to this problem.

http://weblogs.asp.net/rashid/archive/2009/04/15/adaptive-rendering-in-asp-net-mvc.aspx


Examples related to ajax

Getting all files in directory with ajax Cross-Origin Read Blocking (CORB) Jquery AJAX: No 'Access-Control-Allow-Origin' header is present on the requested resource Fetch API request timeout? How do I post form data with fetch api? Ajax LARAVEL 419 POST error Laravel 5.5 ajax call 419 (unknown status) How to allow CORS in react.js? Angular 2: How to access an HTTP response body? How to post a file from a form with Axios

Examples related to asp.net-mvc

Using Lato fonts in my css (@font-face) Better solution without exluding fields from Binding Vue.js get selected option on @change You must add a reference to assembly 'netstandard, Version=2.0.0.0 How to send json data in POST request using C# VS 2017 Metadata file '.dll could not be found The default XML namespace of the project must be the MSBuild XML namespace How to create roles in ASP.NET Core and assign them to users? The model item passed into the dictionary is of type .. but this dictionary requires a model item of type How to use npm with ASP.NET Core

Examples related to json

Use NSInteger as array index Uncaught SyntaxError: Unexpected end of JSON input at JSON.parse (<anonymous>) HTTP POST with Json on Body - Flutter/Dart Importing json file in TypeScript json.decoder.JSONDecodeError: Extra data: line 2 column 1 (char 190) Angular 5 Service to read local .json file How to import JSON File into a TypeScript file? Use Async/Await with Axios in React.js Uncaught SyntaxError: Unexpected token u in JSON at position 0 how to remove json object key and value.?

Examples related to asp.net-ajax

How to pass multiple parameters from ajax to mvc controller? window.open with target "_blank" in Chrome Setting Access-Control-Allow-Origin in ASP.Net MVC - simplest possible method Disable asp.net button after click to prevent double clicking How can I convince IE to simply display application/json rather than offer to download it? How to send a model in jQuery $.ajax() post request to MVC controller method How to post ASP.NET MVC Ajax form using JavaScript rather than submit button How can I deserialize JSON to a simple Dictionary<string,string> in ASP.NET? jQuery $(document).ready and UpdatePanels? ASP.NET MVC controller actions that return JSON or partial html