Действия контроллера ASP.NET MVC, возвращающие JSON или частичный HTML

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

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
419
0
604 112
11
Перейти к ответу Данный вопрос помечен как решенный

Ответы 11

Ответ принят как подходящий

В своем методе действия верните 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 по умолчанию возвращает text / plain в качестве contentType.
Это перегружено, поэтому вы также можете:

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

прости, Фил! это на самом деле не отвечает на вопрос, не так ли? это определенно полезно, но, как говорит Брэд, вам нужно каким-то образом узнать, что они просят, и вернуть результат соответственно.

Simon_Weaver 27.01.2009 08:07

см. мой несколько связанный (ну тот, который привел меня сюда) вопрос на stackoverflow.com/questions/482363/…

Simon_Weaver 27.01.2009 08:08

если найдете ответ, дайте ссылку в самом вопросе. Также я не думаю, что проверять это, потому что ответ - правильный ответ.

Cherian 18.02.2009 17:32
stackoverflow.com/questions/320291/… связан
Cherian 18.02.2009 17:33

Каково полное имя этого класса Json?

Josh Withee 19.12.2018 20:35

@Haacked: Я читал ваш блог Json угон, не могли бы вы объяснить, почему изменение Get на Post предотвращает атаку? Я задал этот вопрос здесь: stackoverflow.com/questions/61995800/…

Hooman Bahreini 28.05.2020 01:07

Потому что атака зависит от злоумышленника, использующего тег скрипта с src, установленным для вашего кода. Если ваш код отвечает только на POST, он не будет загружен в чей-то тег скрипта.

Haacked 29.05.2020 03:39

Еще один хороший способ работать с данными 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);
    }
);

Это вообще не отвечает на вопрос.

Aaronaught 14.09.2011 18:12

@Aaronaught На самом деле первая часть return Json(new {foo = "bar", baz = "Blech"}); делает!

SparK 21.03.2016 21:28

Также рассмотрите возможность $ .post stackoverflow.com/questions/751218/… (по умолчанию ASP.Net MVC отключает запросы JSON Get по соображениям безопасности)

Greg 24.04.2018 18:21

Чтобы ответить на вторую половину вопроса, вы можете вызвать:

return PartialView("viewname");

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

так разве вопрос не остался без ответа?

Simon_Weaver 27.01.2009 08:04

Это не отвечает на вопрос.

Aaronaught 14.09.2011 18:14

он ищет запрос ajax для получения html с помощью PartialView, требуется обновление страницы, если вы не вернете представление из метода действия с помощью вызова ajax

Chris McGrath 03.04.2012 01:11

Я думаю, вам следует рассмотреть 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.info('got %o with status %s', data, textStatus);
        }, "json"); // or xml, html, script, json, jsonp or text

Надеюсь это поможет Джеймс

Спасибо, Джеймс, это может быть очень полезно для создания своего рода веб-сайта и REST API с использованием одних и тех же действий контроллера.

NathanD 01.10.2009 17:34

Если у меня много таких методов в моем контроллере, могу ли я сделать это в более общем плане?

Seph 10.06.2012 17:45

В каком пространстве имен находится класс Json? Какая зависимость для project.json? заранее спасибо

Andrei 23.07.2016 00:16

Это Класс JsonResult из System.Web.Mvc (в System.Web.Mvc.dll) @Andrei

James Green 26.07.2016 10:58

Спасибо, нашел. Может быть, обновить ответ, чтобы отразить новый API? Кстати, я использую ядро ​​dotnet, где это Microsoft.AspNetCore.Mvc.JsonResult.

Andrei 26.07.2016 19:26

Возможно, вы захотите взглянуть на эту очень полезную статью, которая очень хорошо освещает это!

Просто подумал, что это может помочь людям, которые ищут хорошее решение этой проблемы.

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

Для тех, кто перешел на MVC 3, вот отличный способ Использование MVC3 и Json

вы также можете использовать ту же технику, что и в этой статье в MVC 2

longhairedsi 13.04.2011 01:20

Альтернативное решение с структура кодирования

Возврат действия 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())

Действие return 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())

Я обнаружил пару проблем с реализацией вызовов 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);
}

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;


        }
    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 07.09.2017 14:32

Поскольку ваш код показывает, что он возвращает JSON, тип возврата должен быть JsonResult, а не ActionResult

noobprogrammer 06.05.2020 10:53

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

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 для входящего запроса, чтобы узнать, является ли значение заголовка X-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

Другие вопросы по теме