关于ajax:返回JSON或部分html的ASP.NET MVC控制器操作

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

我试图创建控制器操作,根据参数返回JSON或部分HTML。获得异步返回到MVC页的结果的最佳方法是什么?


在您的action方法中,返回json(object)将json返回到您的页面。

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

然后使用Ajax调用action方法。您可以使用视图页中的一个助手方法,例如

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

somemethod是一个javascript方法,然后评估返回的JSON对象。

如果要返回纯字符串,只需使用ContentResult:

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

默认情况下,ContentResult返回文本/纯文本作为其ContentType。这是可重载的,因此您还可以执行以下操作:

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


我认为你应该考虑请求的接受类型。我在当前项目中使用它返回正确的内容类型,如下所示。

您在控制器上的操作可以像在请求对象上一样测试它。

1
2
3
4
5
6
7
8
9
10
11
12
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来获取它:

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

希望这有帮助詹姆斯


处理JSON数据的另一个好方法是使用jquery getjson函数。你可以打电话给

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

方法从jquery getjson方法中简单地…

1
2
3
4
5
6
$.getJSON("../SomeActionMethod", { id: someId },
    function(data) {
        alert(data.foo);
        alert(data.baz);
    }
);


我发现使用jquery实现MVC Ajax GET调用时存在一些问题,这些问题让我头疼,所以在这里共享解决方案。

  • 确保在Ajax调用中包含数据类型"json"。这将自动为您解析返回的JSON对象(假定服务器返回有效的JSON)。
  • 包括JsonRequestBehavior.AllowGet;如果没有此MVC,则返回HTTP 500错误(客户机上指定了dataType: json)。
  • cache: false添加到$.ajax调用中,否则最终将得到HTTP 304响应(而不是HTTP 200响应),服务器将不会处理您的请求。
  • 最后,JSON是区分大小写的,因此元素的大小写需要在服务器端和客户机端匹配。
  • jQuery示例:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    $.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代码示例:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    [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);
    }


    要回答另一半问题,您可以致电:

    1
    return PartialView("viewname");

    当您想返回部分HTML时。您只需要找到一些方法来决定请求是否需要JSON或HTML,可能是基于URL部分/参数。


    引入框架的替代解决方案

    动作返回json

    控制器

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

    剃刀页

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    @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

    控制器

    1
    2
    3
    4
    5
        [HttpGet]
        public ActionResult SomeActionMethod()
        {
            return IncView();
        }

    剃刀页

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


    你可能想看看这篇非常有用的文章,它很好地涵盖了这一点!

    只是觉得它可以帮助人们寻找一个好的解决方案。

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


    对于那些升级到MVC 3的人来说,这里是一个很好的方法使用MVC3和JSON


    partialView结果和jsonReuslt从基类actionResult继承。因此,如果确定返回类型,则动态地将方法输出声明为actionResult。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    public ActionResult DynamicReturnType(string parameter)
            {
                if (parameter =="JSON")
                    return Json("<JSON>", JsonRequestBehavior.AllowGet);
                else if (parameter =="PartialView")
                    return PartialView("<ViewName>");
                else
                    return null;


            }

    1
    2
    3
    4
    5
    6
    7
    8
    9
        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);
                }
            }


    根据请求灵活生成不同输出的方法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    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,以便我们可以从任何地方调用它,就像请求一样。isajaxrequest()扩展方法:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    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_ujavascript_rendering