ASP。NET MVC呈现部分视图与jQuery ajax。

时间:2022-11-30 18:10:32

I have a controller action which renders a partial view:

我有一个控制器动作,它呈现部分视图:

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

and I'm loading the returned content into a dynamic element as follows:

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

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

so this creates a div, and then loads the returned content into that div.

这样就创建了一个div,然后将返回的内容加载到这个div中。

I want to alter this slightly so that the container div is only created if the call to the controller is succesful.

我想稍微修改一下,以便只有在对控制器的调用成功时才创建容器div。

So:

所以:

  1. jQuery calls the controller action
  2. jQuery调用控制器动作。
  3. controller returns PartialView, or null if Id not found
  4. 如果没有找到Id,控制器将返回PartialView或null
  5. If PartialView is returned, the container is created and loaded with the returned content.
  6. 如果返回了PartialView,则创建容器并装载返回的内容。
  7. If the controller doesn't find the Id, no content is created and an alert is displayed.
  8. 如果控制器没有找到Id,则不会创建任何内容并显示警报。

I'd appreciate any pointers on how I could best acheive this.

如果有什么建议,我将非常感激。

2 个解决方案

#1


11  

All load does is return HTML from a server, so why not just append to a temporary div and then get the HTML from it on success?

所有的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();
});

UPDATE:

更新:

If you're expecting an exception then you should handle it. If you're basically allowing the error to occur just to get status != "success" then that's a serious code smell. You should catch the error and return a different 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);
    }
}

Then you're guaranteed to always get a valid HTML response and if you don't, then your basic error an error occured will come into play.

然后,您将保证始终得到有效的HTML响应,如果不这样做,那么发生的基本错误将会发挥作用。

#2


11  

in your case i would use $.ajax instead of .load() gives you more control over the flow + feels more clean

在你的情况下,我会用$。ajax而不是.load()为您提供了对flow +的更多控制,使您感觉更干净

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

concerning the error state - i also hate relying on exceptions - ugly and inefficient, you have several ways to handle this:

关于错误状态——我也讨厌依赖异常——丑陋而低效,您有几种方法来处理这个问题:

  1. return only JSON from your views and bind the returned data using some sort of templating solution, this way you can return an error object with a specific error message and handle all errors the same way(think this is the best solution).
  2. 仅从视图返回JSON并使用某种模板解决方案绑定返回的数据,这样就可以返回带有特定错误消息的错误对象,并以相同的方式处理所有错误(认为这是最好的解决方案)。
  3. return a 204 success status code -no response which is like returning null from your action - then check the status code and pop up the error message.
  4. 返回一个204成功的状态码——没有响应,就像从操作返回null一样——然后检查状态码并弹出错误消息。
  5. return a 278 success status code(not a real status code but is counts for success and lets you also send data) - here you send a json object with the error message which tou can parse and sow a nice error message (saw this 278 solution here in SO sometime ago).
  6. 成功返回一个278状态代码(而不是一个真正的状态代码,但成功的数量,让你也发送数据)- - -在这里你发送json对象的错误消息,或许可以解析和播种一个错误消息(看到这278解决方案在某个时候前)。
  7. return a different view for the error - but then you have to insert it to the container or a dummy container to check if there is an error if you want to take more actions.
  8. 为错误返回一个不同的视图——但是如果您想执行更多操作,则必须将其插入到容器或虚拟容器中,以检查是否存在错误。

in my code i use $(document).ajaxSend(..) to globally check all Ajax responses for 278 code and show the error messages if there is any, or call the original hooked success function.

在我的代码中,我使用$(document). ajaxsend(.. .)全局检查所有Ajax响应的278个代码,并显示错误消息(如果有的话),或者调用原始的hook success函数。

To return the error from the action i use the following result

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

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

where ErrorResult can be an anonymous object or an object that implement an interface with a property of ErrorMessage so you will know what to look for at the JS

ErrorResult可以是一个匿名对象,也可以是一个实现带有ErrorMessage属性的接口的对象,这样您就知道在JS中应该查找什么了

#1


11  

All load does is return HTML from a server, so why not just append to a temporary div and then get the HTML from it on success?

所有的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();
});

UPDATE:

更新:

If you're expecting an exception then you should handle it. If you're basically allowing the error to occur just to get status != "success" then that's a serious code smell. You should catch the error and return a different 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);
    }
}

Then you're guaranteed to always get a valid HTML response and if you don't, then your basic error an error occured will come into play.

然后,您将保证始终得到有效的HTML响应,如果不这样做,那么发生的基本错误将会发挥作用。

#2


11  

in your case i would use $.ajax instead of .load() gives you more control over the flow + feels more clean

在你的情况下,我会用$。ajax而不是.load()为您提供了对flow +的更多控制,使您感觉更干净

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

concerning the error state - i also hate relying on exceptions - ugly and inefficient, you have several ways to handle this:

关于错误状态——我也讨厌依赖异常——丑陋而低效,您有几种方法来处理这个问题:

  1. return only JSON from your views and bind the returned data using some sort of templating solution, this way you can return an error object with a specific error message and handle all errors the same way(think this is the best solution).
  2. 仅从视图返回JSON并使用某种模板解决方案绑定返回的数据,这样就可以返回带有特定错误消息的错误对象,并以相同的方式处理所有错误(认为这是最好的解决方案)。
  3. return a 204 success status code -no response which is like returning null from your action - then check the status code and pop up the error message.
  4. 返回一个204成功的状态码——没有响应,就像从操作返回null一样——然后检查状态码并弹出错误消息。
  5. return a 278 success status code(not a real status code but is counts for success and lets you also send data) - here you send a json object with the error message which tou can parse and sow a nice error message (saw this 278 solution here in SO sometime ago).
  6. 成功返回一个278状态代码(而不是一个真正的状态代码,但成功的数量,让你也发送数据)- - -在这里你发送json对象的错误消息,或许可以解析和播种一个错误消息(看到这278解决方案在某个时候前)。
  7. return a different view for the error - but then you have to insert it to the container or a dummy container to check if there is an error if you want to take more actions.
  8. 为错误返回一个不同的视图——但是如果您想执行更多操作,则必须将其插入到容器或虚拟容器中,以检查是否存在错误。

in my code i use $(document).ajaxSend(..) to globally check all Ajax responses for 278 code and show the error messages if there is any, or call the original hooked success function.

在我的代码中,我使用$(document). ajaxsend(.. .)全局检查所有Ajax响应的278个代码,并显示错误消息(如果有的话),或者调用原始的hook success函数。

To return the error from the action i use the following result

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

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

where ErrorResult can be an anonymous object or an object that implement an interface with a property of ErrorMessage so you will know what to look for at the JS

ErrorResult可以是一个匿名对象,也可以是一个实现带有ErrorMessage属性的接口的对象,这样您就知道在JS中应该查找什么了