ASP.NET MVC使用jQuery ajax渲染局部视图

时间:2010-09-06 11:45:59

标签: asp.net-mvc ajax jquery partial-views

我有一个控制器动作,可以呈现局部视图:

public ActionResult Details(int id)
{
    DetailsViewModel model = 
        ModelBuilder.GetDetailsViewModel(id, _repository);
    return PartialView("Details", model);
}

我将返回的内容加载到动态元素中,如下所示:

$container = appendContainer(); // adds a div to the dom with the correct id
$container.load("MyController/Details", function(response, status, xhr) {
    if (status != "success") {
        $(container).html('an error has occured');
    }
});

所以这会创建一个div,然后将返回的内容加载到该div中。

我想略微改变它,以便只在调用时创建容器div 控制器是成功的。

所以:

  1. jQuery调用控制器操作
  2. controller返回PartialView,如果未找到Id,则返回null
  3. 如果返回PartialView,则会创建容器并使用返回的内容加载容器。
  4. 如果控制器未找到Id,则不会创建任何内容并显示警告。
  5. 我很感激有关如何最好地实现这一目标的任何指示。

2 个答案:

答案 0 :(得分:12)

在你的情况下,我会使用$ .ajax而不是.load() 让您更好地控制流量+感觉更干净

$.ajax({
url: "MyController/Details",
   type: "GET",
   success: function (response, status, xhr)
   {
      var jqContainer = appendContainer();
      jqContainer.html(response);
   },
   error:function(XMLHttpRequest, textStatus, errorThrown)
   {
     //show the error somewhere - but this is a bad solution
   }
});

关于错误状态 - 我也讨厌依赖异常 - 丑陋和低效, 你有几种方法可以解决这个问题:

  1. 仅从您的视图返回JSON并使用某种模板解决方案绑定返回的数据,这样您就可以返回带有特定错误消息的错误对象并以相同的方式处理所有错误(认为这是最佳解决方案)。
  2. 返回204成功状态代码 - 无响应,就像从您的操作中返回null - 然后检查状态代码并弹出错误消息。
  3. 返回一个278成功状态代码(不是一个真实的状态代码,但是成功的数量并让你也发送数据) - 在这里你发送一个带有错误消息的json对象,tou可以解析并播种一个很好的错误消息(锯这个278解决方案在此之前的某个时候)。
  4. 返回错误的不同视图 - 但是如果要采取更多操作,则必须将其插入容器或虚拟容器以检查是否存在错误。
  5. 在我的代码中,我使用$(document).ajaxSend(..)全局检查278代码的所有Ajax响应,并显示错误消息(如果有),或者调用原始的hooked success函数。

    要从操作中返回错误,请使用以下结果

        public class AjaxErrorWithDetailsResult : JsonResult
        {
        public object ErrorResult { get; set; }
    
        public AjaxErrorWithDetailsResult(object errorResult)
        {
            this.ErrorResult = errorResult;
        }
    
    
        public override void ExecuteResult(ControllerContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }
            this.Data = ErrorResult;
            context.HttpContext.Response.StatusCode = 278;
            base.ExecuteResult(context);
        }
    }
    

    其中ErrorResult可以是匿名对象,也可以是实现具有ErrorMessage属性的接口的对象,因此您将知道在JS中要查找的内容

答案 1 :(得分:11)

所有load都是从服务器返回HTML,那么为什么不只是附加到临时div,然后在成功时从中获取HTML?

var $dummy = $("<div>");
$dummy.load("MyController/Details", function(response, status, xhr) {
    var $container = appendContainer();
    if (status != "success") {
        $container.html('an error has occured');
    }
    else
    {
        $container.html($dummy.html());
    }
    $dummy.remove();
});

<强>更新

如果您期待异常,那么您应该处理它。如果你基本上允许错误发生只是为了获得status != "success"那么这是一个严重的代码味道。您应该捕获错误并返回不同的PartialView。

public ActionResult Details(int id)
{
    try
    {
        DetailsViewModel model = 
            ModelBuilder.GetDetailsViewModel(id, _repository);
        return PartialView("Details", model);
    }
    catch (SomeException ex)
    {
        return PartialView("Error", ex.Message);
    }
}

然后您可以保证始终获得有效的HTML回复,如果不这样做,那么您的基本错误an error occured将会发挥作用。