如何通过ajax调用控制器在MVC5中呈现局部视图并返回HTML

19
如何使用AJAX加载已呈现为HTML的完整局部视图(因此我只需设置div.html)
我需要进行AJAX调用以调用控制器操作,该操作将呈现完整的局部视图(红色),并将其附加到当前加载的局部视图的末尾?
[我知道如何附加到DOM和如何进行AJAX调用]
我需要知道最佳管道方法是什么,动作应返回什么类型的ActionResult,是否有已经内置的机制可避免重复造轮子? enter image description here

4
使用$.load调用控制器方法返回partialview,并返回部分视图名称"_PartialViewName"的部分视图。 - Guruprasad J Rao
从控制器操作中返回partialView作为ActionResult,这个操作是由ajax调用的?那么它会返回渲染后的HTML,这样我就可以将其放入div中了吗? - Paceman
1
你不需要使用 ajax,只需使用 $.load - Guruprasad J Rao
好的,谢谢。我需要研究一下如何使用$.load。谢谢 +1 - Paceman
随时开工,愉快编码.. :) - Guruprasad J Rao
1
@Guruprasad Rao的建议使用$(selector).load(URL,data,callback);是目前最好的解决方案。 - Denny Jacob
2个回答

24

ASP.NET MVC中有内置的Ajax助手程序,可以处理基本场景。

您需要安装并引用jquery.unobtrusive-ajax JavaScript库(需要依赖jQuery)。然后在您的主视图(比如index.cshtml)中放置以下代码:

Index.cshtml

@Ajax.ActionLink("Load More Posts", "MorePosts", new AjaxOptions()
{
    HttpMethod = "GET",
    AllowCache = false,
    InsertionMode = InsertionMode.InsertAfter,
    UpdateTargetId = "posts-wrapper"
})

<div id="posts-wrapper"></div>

注意: @Ajax.ActionLink 助手接受 AjaxOptions 参数以进行更多的自定义。

在控制器中(假设是 HomeController.cs),您应该返回 PartialViewResult:

public ActionResult MorePosts(int? offset, int? count)
{
    IEnumerable<Post> posts = myService.GetNextPosts(offset, count); 
    return PartialView(posts);
}

最后您需要定义 MorePosts.cshtml 部分视图:

@model IEnumerable<Post>

@{
    Layout = null;
}

@foreach (var post in Model)
{
    <div class="post">
        <div>>@post.Prop1</div>
        <div>@post.Prop2</div>
    </div>
    <hr />
}

就是这样,当某个用户点击“加载更多”按钮时,将会加载更多的文章。

注意1:您可以实现OnBegin函数来实现实际逻辑,以决定要加载哪些文章(例如,获取已加载文章的最后一个ID并将其发送到服务器)。

注意2:可以使用自定义的jQuery.ajax调用(而不是jquery.unobtrusive),来实现相同的结果。唯一的区别是手动设置ajax调用和点击事件。


希望这有所帮助。如果需要,我可以撰写更完整的示例。


我在进行AJAX调用时采用了更手动的方法,使用完整的$.ajax以便我能够跟踪错误。谢谢。 - Paceman
@Viktor,您能否指导我们如何使此调用自动化而不是手动化,并获取主视图上的参数。 - Jyotish Singh

2

我建议从NUGET获取Westwind.Web.Mvc库,您可以将任何视图运行为字符串,以作为JSON结果返回。

public JsonResult GetPosts()
{
    string postsHtml = ViewRenderer.RenderPartialView("~/views/yourcontroller/_PostsPartial.cshtml",model);

    return Json(new { html = postsHtml });
}

如评论中的@Guruprasad所说,您可以使用return PartialView(model)从MVC控制器简单地返回部分视图。但是,使用RenderPartialView,您可以将其作为字符串获取,如果需要,可以与任何其他值一起输出为JSON格式。如果选择使用WebAPI,这将起作用,因为它没有渲染视图的能力。

3
如果你正在使用WebAPI,那么你应该避免返回HTML。 - freedomn-m
@Luke 仅仅因为两者具有相似的控制器语法并不意味着它们适用于同一目的。Web API 旨在处理业务逻辑,而 Asp.NET MVC 应该处理视图/展示逻辑。为了保持关注点分离,您的业务层不应定义视图的布局,即 HTML。这样做的好处是能够在多个截然不同的前端应用程序中使用相同的 API。例如,C# Windows 10 应用程序、HTML 5 浏览器应用程序和 Objective-C iOS 应用程序。 - Dan Bechard
@Dan 我倾向于同意你的观点,这不是最佳实践,最好的方法是返回值并使用Angular或其他工具将其呈现到模板中。然而,关注点的分离确实体现在代码的分层和模块化上,而不一定是传递值以呈现视图的方式。在这种情况下,呈现视图和生成视图模型之间的分离仍然存在,只是你使用了不同的方法来产生最终的HTML结果。你同意吗? - Luke
@Luke 是的,有时候业务逻辑和展示逻辑都在 Web API 项目中,前端应用程序只是一个“哑巴”演示器,只是输出结果。但在这种情况下,我想知道为什么你需要前端应用程序?虽然为了高可扩展性,在服务器上呈现静态页面可能有一些缓存相关的原因,但我不建议在没有认真考虑的情况下采用这种方法。无论您的架构决策如何,客户端都需要进行错误处理,因此您永远无法真正拥有真正的“愚蠢”前端。 - Dan Bechard
1
抱歉如果我看起来有点困惑,我喝了几杯啤酒!我试图表达的观点是,业务逻辑或视图“逻辑”都不应该驻留在WebAPI中,我并没有说它应该。我只是提供了一种从WebAPI内部呈现视图的方法。视图仍然是视图,生成的模型仍然可以来自业务逻辑层,可以在MVC控制器和WebAPI控制器之间共享。 - Luke
显示剩余6条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接