Дії контролера ASP.NET MVC, які повертають JSON або частковий html


406

Я намагаюся створити дії контролера, які повернуть або JSON, або частковий html залежно від параметра. Який найкращий спосіб повернути результат асинхронно на сторінку MVC?

Відповіді:


519

У своєму способі дій поверніть Json (об'єкт), щоб повернути JSON на свою сторінку.

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

Тоді просто викличте метод дії за допомогою Ajax. Ви можете скористатися одним із допоміжних методів з ViewPage, таким як

<%= Ajax.ActionLink("SomeActionMethod", new AjaxOptions {OnSuccess="somemethod"}) %>

SomeMethod був би методом javascript, який потім оцінює повернений об'єкт Json.

Якщо ви хочете повернути звичайну рядок, ви можете просто скористатися ContentResult:

public ActionResult SomeActionMethod() {
    return Content("hello world!");
}

ContentResult за замовчуванням повертає текст / звичайну як його contentType.
Це можна завантажити, тому ви також можете зробити:

return Content("<xml>This is poorly formatted xml.</xml>", "text/xml");

9
вибачте Філе! це насправді не відповідає на питання це робить? це, безумовно, корисно, але, як каже брад, потрібно якось з’ясувати, що вони просять, і відповідно повернути результат.
Simon_Weaver

побачити мій кілька пов'язаного (ну той , який привів мене сюди) питання на stackoverflow.com/questions/482363 / ...
Simon_Weaver

9
якщо ви знайдете відповідь, зв’яжіть її у самому питанні. Крім того, я не думаю, що перевірити це як відповідь - це правильна річ.
Черіан


Яке цілком кваліфіковане ім'я цього класу Json?
Джош Вітхі

112

Я думаю, ви повинні врахувати AcceptTypes запиту. Я використовую це у своєму поточному проекті для повернення правильного типу вмісту, як описано нижче.

Ваша дія на контролері може перевірити його як на об'єкт запиту

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"))
{
   //
}

Потім можна реалізувати aspx подання для задоволення часткового випадку відповіді xhtml.

Потім у jQuery ви можете отримати його, передаючи параметр типу як 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

Сподіваюся, що це допомагає Джеймсу


5
Дякую Джеймсу, що може бути дуже корисним для створення веб-сайту та API REST, використовуючи ті ж дії Controller.
NathanD

Якщо у мене в контролері є багато подібних методів, чи є спосіб зробити це більш загально?
Seph

У якому просторі імен клас Json? Яка залежність для project.json? Заздалегідь дякую
Андрій

1
Це клас JsonResult від System.Web.Mvc (в System.Web.Mvc.dll) @Andrei
James Green

Дякую, знайшли. Можливо, оновіть відповідь, щоб відобразити новий API? До речі, я використовую ядро ​​dotnet, де Microsoft.AspNetCore.Mvc.JsonResult.
Андрій

78

Ще один приємний спосіб поводження з даними JSON - це використання функції JQuery getJSON. Ви можете зателефонувати на

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

Метод з методу jquery getJSON простим ...

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

15
Це зовсім не відповідає на питання.
Aaronaught

2
@Aaronaught Насправді перша частина return Json(new {foo="bar", baz="Blech"});робить!
SparK

Також розглянемо $ .POST stackoverflow.com/questions/751218 / ... (ASP.Net MVC по замовчуванням відключити JSON Отримати запити з міркувань безпеки)
Грег

50

Я знайшов пару питань, що реалізують дзвінки MVC ajax GET з JQuery, що викликало у мене головний біль, тому спільне використання тут рішень.

  1. Обов’язково включіть тип даних "json" у виклик ajax. Це автоматично розбере повернутий для вас об’єкт JSON (якщо сервер повертає дійсний json).
  2. Включіть JsonRequestBehavior.AllowGet; без цього MVC повертав помилку HTTP 500 (із dataType: jsonвказаною на клієнті).
  3. Додайте cache: falseдо виклику $ .ajax, інакше ви отримаєте відповіді HTTP 304 (замість відповідей HTTP 200), і сервер не обробить ваш запит.
  4. Нарешті, json чутливий до регістру, тому корпус елементів повинен відповідати на стороні сервера та клієнта.

Зразок 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);
  }
});

Зразок коду MVC:

[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);
}

13

Щоб відповісти на другу половину питання, ви можете зателефонувати:

return PartialView("viewname");

коли ви хочете повернути частковий HTML. Вам просто доведеться знайти спосіб вирішити, чи потрібен запит JSON або HTML, можливо, виходячи з частини / параметра URL-адреси.


2
так хіба питання не залишається без відповіді?
Simon_Weaver

2
Це не дає відповіді на запитання.
Aaronaught

він шукає запит ajax, щоб отримати html за допомогою PartialView, потребує оновлення сторінки, якщо ви не повернете подання з методу дії за допомогою дзвінка ajax
Кріс МакГрат

7

Альтернативне рішення з рамкою інкодування

Дія повернення json

Контролер

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

Сторінка бритви

@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())

Дія повернення html

Контролер

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

Сторінка бритви

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


4

PartialViewResult і JSONReuslt успадковують від базового класу ActionResult. тому, якщо вирішено тип повернення, динамічно оголошуйте вихідний метод як ActionResult.

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


        }


2
    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);
            }
        }

Ви можете додати трохи більше інформації про те, що це робить?
RealCheeseLord

Оскільки ваш код показує, що це повернення JSON, тип повернення повинен бути JsonResult, а не ActionResult
noobprogrammer

0

Гнучкий підхід для отримання різних результатів на основі запиту

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);
  }
}

Request.IsAjaxRequest()Метод досить простий: він просто перевіряє HTTP заголовки для вхідного запиту , щоб побачити , якщо значення Х-Requested-With заголовок XMLHttpRequest, який автоматично додається в більшості браузерів і рамок AJAX.

Спеціальний метод розширення, щоб перевірити, чи є запит на json чи ні, щоб ми могли викликати його з будь-якого місця, як і метод розширення Request.IsAjaxRequest ():

using System;
using System.Web;

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

Джерело: https://www.safaribooksonline.com/library/view/programming-aspnet-mvc/9781449321932/ch06.html#_javascript_rendering

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.