Я пытаюсь создать действия контроллера, которые будут возвращать либо JSON, либо частичный html в зависимости от параметра. Как лучше всего получить результат, возвращаемый на страницу MVC асинхронно?
В своем методе действия верните 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");
см. мой несколько связанный (ну тот, который привел меня сюда) вопрос на stackoverflow.com/questions/482363/…
если найдете ответ, дайте ссылку в самом вопросе. Также я не думаю, что проверять это, потому что ответ - правильный ответ.
Каково полное имя этого класса Json?
@Haacked: Я читал ваш блог Json угон, не могли бы вы объяснить, почему изменение Get
на Post
предотвращает атаку? Я задал этот вопрос здесь: stackoverflow.com/questions/61995800/…
Потому что атака зависит от злоумышленника, использующего тег скрипта с src, установленным для вашего кода. Если ваш код отвечает только на POST, он не будет загружен в чей-то тег скрипта.
Еще один хороший способ работать с данными 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 На самом деле первая часть return Json(new {foo = "bar", baz = "Blech"});
делает!
Также рассмотрите возможность $ .post stackoverflow.com/questions/751218/… (по умолчанию ASP.Net MVC отключает запросы JSON Get по соображениям безопасности)
Чтобы ответить на вторую половину вопроса, вы можете вызвать:
return PartialView("viewname");
когда вы хотите вернуть частичный HTML. Вам просто нужно найти способ решить, нужен ли запрос JSON или HTML, возможно, на основе части / параметра URL.
так разве вопрос не остался без ответа?
Это не отвечает на вопрос.
он ищет запрос ajax для получения html с помощью PartialView, требуется обновление страницы, если вы не вернете представление из метода действия с помощью вызова ajax
Я думаю, вам следует рассмотреть 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 с использованием одних и тех же действий контроллера.
Если у меня много таких методов в моем контроллере, могу ли я сделать это в более общем плане?
В каком пространстве имен находится класс Json? Какая зависимость для project.json? заранее спасибо
Это Класс JsonResult из System.Web.Mvc (в System.Web.Mvc.dll) @Andrei
Спасибо, нашел. Может быть, обновить ответ, чтобы отразить новый API? Кстати, я использую ядро dotnet, где это Microsoft.AspNetCore.Mvc.JsonResult.
Возможно, вы захотите взглянуть на эту очень полезную статью, которая очень хорошо освещает это!
Просто подумал, что это может помочь людям, которые ищут хорошее решение этой проблемы.
http://weblogs.asp.net/rashid/archive/2009/04/15/adaptive-rendering-in-asp-net-mvc.aspx
Для тех, кто перешел на MVC 3, вот отличный способ Использование MVC3 и Json
вы также можете использовать ту же технику, что и в этой статье в MVC 2
Альтернативное решение с структура кодирования
Возврат действия 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, которые вызвали у меня головные боли, поэтому поделитесь решениями здесь.
JsonRequestBehavior.AllowGet
; без этого MVC возвращал ошибку HTTP 500 (с указанием dataType: json
на клиенте).cache: false
к вызову $ .ajax, иначе вы в конечном итоге получите ответы HTTP 304 (вместо ответов HTTP 200), и сервер не будет обрабатывать ваш запрос.Пример 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);
}
}
не могли бы вы добавить немного дополнительной информации о том, что это делает?
Поскольку ваш код показывает, что он возвращает JSON, тип возврата должен быть JsonResult, а не ActionResult
Гибкий подход для получения различных результатов в зависимости от запроса
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");
}
}
прости, Фил! это на самом деле не отвечает на вопрос, не так ли? это определенно полезно, но, как говорит Брэд, вам нужно каким-то образом узнать, что они просят, и вернуть результат соответственно.