17

How can use AJAX to load a complete partial view rendered in html (so I just set the div.html)

I need the ajax call to call controller action that will render a complete partial view (red) and append it at the end of the currently loaded one?

[I know how to append to DOM and how to make AJAX calls]

I need to know what is the best plumbing approach for this, what type of ActionResult should the action return and if there is an already built-in mechanism for this so to avoid reinventing the wheel?

enter image description here

Luke
  • 19,970
  • 26
  • 98
  • 180
Paceman
  • 1,901
  • 3
  • 17
  • 26

2 Answers2

23

There is built-in ajax helpers in ASP.NET MVC which can cover the basic scenarios.

You need to install and refer jquery.unobtrusive-ajax JavaScript library ( + jQuery dependency). Then in your main view (let's say index.cshtml) put following code:

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>

Note: @Ajax.ActionLink helper accepts AjaxOptions parameter for more customizations.

In the controller (let's say HomeController.cs) you should return PartialViewResult:

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

Finally you define the MorePosts.cshtml partial view:

@model IEnumerable<Post>

@{
    Layout = null;
}

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

And that's it. When some user clicks on Load More button, more posts will be loaded.

Note 1: you can implement OnBegin function to implement the actual logic for deciding which are the next posts to load (ex. get the id of the last loaded post and send it to the server).

Note 2: the same result can be achieved with custom jQuery.ajax calls (without jquery.unobtrusive). The only differences will be the manual ajax calls and click events.


Hope this helps. I can write a more complete example if needed.

Viktor Bahtev
  • 4,568
  • 2
  • 27
  • 37
  • I used this with a more manual approach when making the AJAX call, using full $.ajax just so I can track errors. Thanks – Paceman Sep 18 '15 at 02:20
  • @Viktor Could you please guide us how to make this call as automatic not manual with parameters which we will get on main view. – Jyotish Singh Oct 04 '16 at 05:18
2

I recommend getting the Westwind.Web.Mvc library from NUGET and you can run any of your views to a string to return back as a JSON result

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

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

As @Guruprasad said in the comments, you can simply return back a partial view from an MVC controller using return PartialView(model), but with the RenderPartialView you get it as a string that you can output as JSON along with any other values if required. This will work if you choose to use WebAPI, because it doesn't have the ability to render a view built in.

Luke
  • 19,970
  • 26
  • 98
  • 180
  • You can stick a entire html rendering into a JSON property? that's handy. ViewRenderer.RenderPartialView is also handy. Thanks, I will check it this works for me. – Paceman Sep 16 '15 at 13:53
  • @InvisiblePanda did you read the post? It doesn't render it like PartialView() does, this renders the view out to a string. – Luke Sep 16 '15 at 13:58
  • 3
    If you're using WebAPI, you probably shouldn't be returning HTML. – freedomn-m Sep 16 '15 at 14:16
  • @freedomn-m I would highly disagree with that statement – Luke Sep 16 '15 at 14:16
  • ...and Asp.net MVC Controller and Web API Controllers are basically the same thing in the latest version, they have been unified. – Luke Sep 16 '15 at 14:26
  • @Luke Just because the two have similar controller syntax doesn't mean they're meant for the same thing. Web API is meant to handle business logic, whereas Asp.NET MVC should handle view/presentation logic. In order to preserve separation of concerns, your business layer should not define the layout of your view, i.e., HTML. The benefit of this is the ability to consume the same API in multiple, vastly different front-end applications. For instance, a C# Windows 10 app, an HTML 5 browser app, and an Objective-C iOS app. – Dan Bechard May 06 '16 at 20:18
  • @Dan I'd tend to agree with you that this isn't the best practice, it would be better to return the values and render then to a template with Angular or something. However, the separation of concerns really comes into play with the layering and modularisation of the code, not necessarily what is passing the values to render your view. In this case, the separation between what is rendering the view and generating the viewmodel for the view is still separated, it's just that you're using a different method to produce the final HTML result. Wouldn't you agree? – Luke May 06 '16 at 20:23
  • @Luke It is true, there may be times when *both* the business logic and presentation logic reside in the Web API project, and the front-end application is a "dummy" presenter which just spits out results. Though in this case, I wonder why you have a front-end application at all? While there may be some cache-related reasons to render static pages on the server for high-scalability I wouldn't recommend starting with that approach without serious consideration. The client needs to do error handling regardless of your architectural decisions, so you can never really have a truly "dumb" front-end. – Dan Bechard May 06 '16 at 20:42
  • @Luke Also, for context, the original comment with which you "highly disagree[d]" stated "you probably shouldn't be returning HTML", not "you should never return HTML". I think it's fair to say returning HTML is the less commonly useful design. – Dan Bechard May 06 '16 at 20:44
  • 1
    Sorry if I seem a bit confused, I've had a few beers! The point I'm trying to make is that neither the business logic or view 'logic' should reside in WebAPI, I haven't said that it should. I have simply provided a way to render a view from within WebAPI. The view is still the view and the model that is generated can still come from the business logic layer that can be shared between MVC controllers and WebAPI controllers. – Luke May 06 '16 at 21:11
  • I'd also like to change my highly disagree to somewhat disagree :) – Luke May 06 '16 at 21:15