2

I have used this set up a number of times but can't see why it is not working here. Essentially the call to the controller seems to work, but returns an empty string, not the partial HTML.

I can render the partial like this so guess it is not the view itself:

@{
    Html.RenderPartial("_MyPartial")
}

Here is the clean AJAX code, which is called from a parent razor view on document ready and calling the controller :

var container = $("#container");

var controllerUrl = "some/url";

var data = {};

$.ajax({
    type: 'POST',
    url: controllerUrl,
    data: data,
    dataType: 'html',
    cache: false,
    success: function(html) {
        // Return HTML to page
        // html is empty string at this point???
        container.html(html);
    },
    error: function(jqXhr, textStatus, errorThrown) {
        // Error occured so return message to page
        container.html('<p>An error has occurred</p><p>' + jqXhr + '<p/><p>' + textStatus + '<p/><p>' + errorThrown + '<p/>');
    }
});

And this is the controller:

   [HttpPost]
   public ActionResult ReportModels()
   {
       var viewModel = new ViewModel(); // props get set in original code

       return PartialView("_MyPartial", viewModel);
   }
GP24
  • 867
  • 2
  • 13
  • 28
  • 1
    var container = $j("#container"); fix code there is j character after dolar – Zergling Dec 22 '15 at 11:10
  • Sorry, that is just a quirk of our codebase, not relevant here. Edited to avoid confusion though, thanks :) – GP24 Dec 22 '15 at 11:11
  • I feel like it must be that I have the options wrong somehow? But dataType is correct...contentType not relevant here? – GP24 Dec 22 '15 at 11:13
  • Did you try removing `dataType: 'html'` from your AJAX call? – Darin Dimitrov Dec 22 '15 at 11:15
  • your type is 'POST' that have to be 'GET' – Zergling Dec 22 '15 at 11:15
  • @Darin, I did try and just confirmed with the same result. - hits the controller fine, but returns empty string. Zergling, POST or GET should work here, but worth checking, thanks :) – GP24 Dec 22 '15 at 11:19
  • 1
    What do you see in the Network tab of your browser? Can you see the AJAX request? What does the server return? – Darin Dimitrov Dec 22 '15 at 11:20
  • This should help http://stackoverflow.com/questions/483091/render-a-view-as-a-string – BenG Dec 22 '15 at 11:21
  • @DarinDimitrov, its is as I would expect and shows the POST to the controller action, status 200. One thing I did notice was that there is no response data available from the request details tabs, but the Headers look okay. – GP24 Dec 22 '15 at 11:23
  • 1
    Okay, that explains why you get an empty string. So now you have to understand why does this controller return an empty string and whether `_MyPartial` is what you think it is. I would start by making this controller action accessible with the GET verb so that I can easily call it from the browser, just by typing its address and try to figure out more about the empty response. Looks like some server side issue. – Darin Dimitrov Dec 22 '15 at 11:25
  • I see, so RenderPartial only confirms the view is okay and I need to work out what's up with the controller. Okay will look at that and the GET set up. Cheers. – GP24 Dec 22 '15 at 11:26
  • You only declared object and referenced it by var viewModel = new ViewModel();. But didn't use in assignment of value. – Muhammad Ashikuzzaman Dec 22 '15 at 12:08
  • try adding contentType in ajax? – Akshay Dec 22 '15 at 13:41
  • Turns out the cause of this was some slightly dodgy logic in a CSRF class that identifies HTML only if it contains "". Adding the appropriate tags to my partial view solved my issue. @DarinDimitrov, since this seems pretty specific to our codebase, shall I delete the question? – GP24 Dec 22 '15 at 14:13

1 Answers1

0

Remove field dataType: 'html' from you ajax. And use this as action method

    [HttpPost]
    public ActionResult ReportModels()
    {
        var partialView = RenderRazorViewToString("_MyPartial", new ViewModel(););
        return Json(partialView);
    }

    public string RenderRazorViewToString(string viewName, object model)
    {
        ViewData.Model = model;
        using (var sw = new StringWriter())
        {
            var viewResult = ViewEngines.Engines.FindPartialView(ControllerContext,
                                                                     viewName);
            var viewContext = new ViewContext(ControllerContext, viewResult.View,
                                         ViewData, TempData, sw);
            viewResult.View.Render(viewContext, sw);
            viewResult.ViewEngine.ReleaseView(ControllerContext, viewResult.View);
            return sw.GetStringBuilder().ToString();
        }
    }