Các hành động của bộ điều khiển ASP.NET MVC trả về JSON hoặc một phần html


406

Tôi đang cố gắng tạo các hành động của bộ điều khiển sẽ trả về JSON hoặc một phần html tùy thuộc vào một tham số. Cách tốt nhất để đưa kết quả được trả về một trang MVC không đồng bộ là gì?

Câu trả lời:


519

Trong phương thức hành động của bạn, trả về Json (đối tượng) để trả JSON về trang của bạn.

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

Sau đó, chỉ cần gọi phương thức hành động bằng Ajax. Bạn có thể sử dụng một trong các phương thức trợ giúp từ ViewPage, chẳng hạn như

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

Một sốMethod sẽ là một phương thức javascript để sau đó đánh giá đối tượng Json được trả về.

Nếu bạn muốn trả về một chuỗi đơn giản, bạn chỉ có thể sử dụng ContentResult:

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

ContentResult theo mặc định trả về một văn bản / đơn giản là contentType của nó.
Điều này là quá tải nên bạn cũng có thể làm:

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

9
xin lỗi phil! Điều này không thực sự trả lời câu hỏi phải không? Nó chắc chắn hữu ích nhưng như brad nói rằng bạn cần tìm hiểu bằng cách nào đó những gì họ đang yêu cầu và trả lại kết quả tương ứng.
Simon_Weaver

thấy hơi liên quan của tôi (cũng là người đã dẫn tôi đến đây) câu hỏi tại stackoverflow.com/questions/482363/...
Simon_Weaver

9
nếu bạn tìm thấy câu trả lời, hãy liên kết nó trong câu hỏi. Ngoài ra tôi không nghĩ kiểm tra điều này vì câu trả lời là điều đúng đắn.
Cherian


Tên đủ điều kiện của lớp Json đó là gì?
Josh Withee

112

Tôi nghĩ bạn nên xem xét các AcceptTypes của yêu cầu. Tôi đang sử dụng nó trong dự án hiện tại của tôi để trả về loại nội dung chính xác như sau.

Hành động của bạn trên bộ điều khiển có thể kiểm tra nó như trên đối tượng yêu cầu

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

Sau đó, bạn có thể triển khai aspx của chế độ xem để phục vụ cho trường hợp phản hồi xhtml một phần.

Sau đó, trong jQuery bạn có thể tìm nạp nó qua tham số kiểu là 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

Hy vọng điều này sẽ giúp James


5
Cảm ơn James, điều đó có thể rất hữu ích để tạo ra một loại trang web và API REST sử dụng cùng các Tác vụ điều khiển.
NathanD

Nếu tôi có nhiều phương thức như thế này trong bộ điều khiển của mình thì có cách nào để tôi có thể làm điều này một cách khái quát hơn không?
Seph

Trong không gian tên là lớp Json? Sự phụ thuộc cho project.json là gì? Cảm ơn trước
Andrei

1
Đó là lớp JsonResult từ System.Web.Mvc (trong System.Web.Mvc.dll) @Andrei
James Green

Cảm ơn bạn, tìm thấy nó. Có thể cập nhật câu trả lời để phản ánh API mới? Btw, tôi đang sử dụng lõi dotnet trong đó Microsoft.AspNetCore.Mvc.JsonResult.
Andrei

78

Một cách hay khác để xử lý dữ liệu JSON là sử dụng hàm JQuery getJSON. Bạn có thể gọi

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

Phương thức từ phương thức jquery getJSON chỉ bằng cách ...

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

15
Điều này không trả lời câu hỏi nào cả.
Aaronaught

2
@Aaronaught Thật ra phần đầu tiên return Json(new {foo="bar", baz="Blech"});nào!
SparK

Ngoài ra, hãy xem xét $ .post stackoverflow.com/questions/751218/ (Mặc định (ASP.Net MVC mặc định để vô hiệu hóa JSON Nhận yêu cầu vì lý do bảo mật)
Greg

50

Tôi đã tìm thấy một số vấn đề khi triển khai các cuộc gọi GET ajax MVC với JQuery khiến tôi đau đầu nên chia sẻ giải pháp tại đây.

  1. Đảm bảo bao gồm kiểu dữ liệu "json" trong lệnh gọi ajax. Điều này sẽ tự động phân tích cú pháp đối tượng JSON được trả về cho bạn (do máy chủ trả về json hợp lệ).
  2. Bao gồm JsonRequestBehavior.AllowGet; không có MVC này đã trả về lỗi HTTP 500 ( dataType: jsonđược chỉ định trên máy khách).
  3. Thêm vào cache: falsecuộc gọi $ .ajax, nếu không, cuối cùng bạn sẽ nhận được phản hồi HTTP 304 (thay vì phản hồi HTTP 200) và máy chủ sẽ không xử lý yêu cầu của bạn.
  4. Cuối cùng, json phân biệt chữ hoa chữ thường, vì vậy vỏ của các phần tử cần khớp với phía máy chủ và phía máy khách.

Mẫu 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);
  }
});

Mã MVC mẫu:

[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

Để trả lời nửa câu hỏi còn lại, bạn có thể gọi:

return PartialView("viewname");

khi bạn muốn trả về một phần HTML. Bạn sẽ phải tìm một số cách để quyết định xem yêu cầu muốn JSON hay HTML, có lẽ dựa trên một phần / tham số URL.


2
Vì vậy, câu hỏi vẫn chưa được trả lời?
Simon_Weaver

2
Điều này không trả lời câu hỏi.
Aaronaught

anh ta đang tìm kiếm một yêu cầu ajax để nhận html bằng PartialView yêu cầu làm mới trang trừ khi bạn trả về chế độ xem từ phương thức hành động bằng cách sử dụng lệnh gọi ajax
Chris McGrath

7

Giải pháp thay thế với khung mã hóa

Hành động trở lại json

Bộ điều khiển

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

Trang dao cạo

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

Hành động trả về html

Bộ điều khiển

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

Trang dao cạo

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


4

PartialViewResult và JSONReuslt kế thừa từ lớp cơ sở ActionResult. vì vậy nếu kiểu trả về được quyết định tự động khai báo phương thức đầu ra là 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);
            }
        }

bạn có thể thêm một chút thông tin về những gì nó làm không?
RealCheeseLord

Vì mã của bạn cho thấy nó trả về JSON, nên kiểu trả về phải là JsonResult chứ không phải ActionResult
noobprogrammer

0

Cách tiếp cận linh hoạt để tạo ra các đầu ra khác nhau dựa trên yêu cầu

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

Các Request.IsAjaxRequest()phương pháp khá đơn giản: nó chỉ kiểm tra các tiêu đề HTTP cho các yêu cầu gửi đến để xem nếu giá trị của X-yêu cầu-Với tiêu đề làXMLHttpRequest , được tự động thêm bởi hầu hết các trình duyệt và các khuôn khổ AJAX.

Phương thức tiện ích mở rộng tùy chỉnh để kiểm tra xem yêu cầu có dành cho json hay không để chúng tôi có thể gọi nó từ bất kỳ đâu, giống như phương thức tiện ích mở rộng Request.IsAjaxRequest ():

using System;
using System.Web;

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

Nguồn: https://www.safaribooksonline.com/l Library / view / programming-aspnet-mvc / 9781449321932 / ch06.html # _javascript_Vndering

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.