ASP.NET MVC 使用 jQuery ajax 呈现部分视图
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3651171/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
ASP.NET MVC rendering partial view with jQuery ajax
提问by fearofawhackplanet
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:
所以:
- jQuery calls the controller action
- controller returns PartialView, or null if Id not found
- If PartialView is returned, the container is created and loaded with the returned content.
- If the controller doesn't find the Id, no content is created and an alert is displayed.
- jQuery 调用控制器动作
- 控制器返回 PartialView,如果未找到 Id,则返回 null
- 如果返回 PartialView,则创建容器并加载返回的内容。
- 如果控制器找不到 Id,则不会创建任何内容并显示警报。
I'd appreciate any pointers on how I could best acheive this.
我很感激有关如何最好地实现这一目标的任何指示。
回答by Avi Pinto
in your case i would use $.ajax instead of .load() gives you more control over the flow + feels more clean
在你的情况下,我会使用 $.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
}
});
concerning the error state - i also hate relying on exceptions - ugly and inefficient, you have several ways to handle this:
关于错误状态——我也讨厌依赖异常——丑陋且效率低下,你有几种方法来处理这个问题:
- 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).
- 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.
- 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).
- 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.
- 仅从您的视图中返回 JSON 并使用某种模板解决方案绑定返回的数据,这样您就可以返回带有特定错误消息的错误对象并以相同的方式处理所有错误(认为这是最好的解决方案)。
- 返回 204 成功状态代码 - 没有响应,就像从您的操作中返回 null - 然后检查状态代码并弹出错误消息。
- 返回一个 278 成功状态代码(不是一个真正的状态代码,但对成功很重要,并且可以让你发送数据) - 在这里你发送一个带有错误消息的 json 对象,你可以解析它并播下一个很好的错误消息(看到这个 278 解决方案前一段时间在这里)。
- 为错误返回不同的视图 - 但是如果您想采取更多操作,则必须将其插入容器或虚拟容器以检查是否存在错误。
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(..) 全局检查 278 代码的所有 Ajax 响应并显示错误消息(如果有),或调用原始挂钩成功函数。
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 中寻找什么
回答by djdd87
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.
如果您期待异常,那么您应该处理它。如果您基本上允许错误发生只是为了获得,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);
}
}
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 响应,如果你没有,那么你的基本错误an error occured
就会发挥作用。