Question

Newbie to MVC here (about a week or two in)...

I'm trying to reload an MVC 5 partial view using Ajax. I've found a number of examples on how to do this, and I've decided to go with using the jQuery load() function.

Here's the code for the controller:

public class NotificationController : Controller
{
    //
    // GET: /Notification/
    public ActionResult Get()
    {
        return PartialView();
    }
}

Here's the html for rendering the partial view:

<div id="notificationArea">
    @Html.Action("Get", "Notification")
</div>

And here's the call I'm making to reload the partial view (on a timer):

 $('#notificationArea').load('@Url.Action("Get","Notification")');

When the partial view is initially rendered using Html.Action everything looks good

Once the timer starts up, calls are made to the Notification controller without a problem, but what's returned is not valid html. It looks something like this:

<$A$> <$B$> id="notificationDropdown"<$C$> class="notificationDropdown"<$D$>> <$E$>
class="notificationsTable"<$F$>>   Operation Title File <$G$> src="/Images/online.png
<$H$> alt="Online"<$I$> /> Operation Test #1 TestFile2.mp4 <$$$>

If I throw in a link created using Url.Action at the bottom of the page and click that link, I get back the same invalid html as above:

<a href="@Url.Action("Get", "Notification")">@Url.Action("Get", "Notification")</a>

I have to assume the call to Html.Action is doing some extra work that isn't done when you just hit the controller url directly, but I have no idea what that is.

I've tried looking through MSDN documentation on the Html.Action without any luck. Could anyone shed some light on what's happening here? What am I missing?

UPDATE:

I realized that I was only capturing what was being rendered by the browser, rather than the full response returned by the call to the Action.

Here is the partial view html:

@model IEnumerable<MyApp.Models.Notification>

<style type="text/css">

.notificationDropdown {
    background-color: #eeeeee;
    position: absolute;
    left: 210px;
    border-left: 3px;
    border-bottom: 3px;
    border-right: 3px;
    border-top: 0px;
    border-style: ridge;
    border-color: #aaaaaa;
}

.notificationsTable {
    margin: 5px;
    border-collapse: collapse;
    border: 1px solid #aaaaaa;
}

    .notificationsTable td {
        border: 1px solid #aaaaaa;
        padding-left: 10px;
        padding-right: 10px;
        padding-top: 3px;
    }

    .notificationsTable th {
        color: #ffffff;
        background-color: #000000;
        border: 1px solid #aaaaaa;
        padding-left: 10px;
        padding-right: 10px;
        padding-top: 3px;
    }
</style>



<div id="notificationDropdown" class="notificationDropdown">
<table class="notificationsTable">
    <thead>
        <tr>
            <th>&nbsp;</th>
            <th>Operation</th>
            <th>Title</th>
            <th>File</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>
                <img src="/Images/online.png" alt="Online" />
            </td>
            <td>Operation</td>
            <td>Test #1</td>
            <td>TestFile2.mp4</td>
        </tr>
    </tbody>
</table>
</div>

Below is the full response I get trying to access the partial view from the action:

<$A$><style>

.notificationDropdown {
    background-color: #eeeeee;
    position: absolute;
    left: 210px;
    border-left: 3px;
    border-bottom: 3px;
    border-right: 3px;
    border-top: 0px;
    border-style: ridge;
    border-color: #aaaaaa;
}

.notificationsTable {
    margin: 5px;
    border-collapse: collapse;
    border: 1px solid #aaaaaa;
}

    .notificationsTable td {
        border: 1px solid #aaaaaa;
        padding-left: 10px;
        padding-right: 10px;
        padding-top: 3px;
    }

    .notificationsTable th {
        color: #ffffff;
        background-color: #000000;
        border: 1px solid #aaaaaa;
        padding-left: 10px;
        padding-right: 10px;
        padding-top: 3px;
    }
</style>



<div</$A$><$B$> id="notificationDropdown"</$B$><$C$> class="notificationDropdown"</$C$><$D$>>
<table</$D$><$E$> class="notificationsTable"</$E$><$F$>>
    <thead>
        <tr>
            <th>&nbsp;</th>
            <th>Operation</th>
            <th>Title</th>
            <th>File</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>
                <img</$F$><$G$> src="/Images/online.png"</$G$><$H$> alt="Online"</$H$><$I$> />
            </td>
            <td>Operation</td>
            <td>Test #1</td>
            <td>TestFile2.mp4</td>
        </tr>
    </tbody>
</table>
</div></$I$><$$$><map><file path="~/Views/Notification/Get.cshtml" encoding="Windows-1252"><node id="A" start="70" length="895" literal="true" /><node id="B" start="965" length="26" literal="true" /><node id="C" start="991" length="29" literal="true" /><node id="D" start="1020" length="13" literal="true" /><node id="E" start="1033" length="27" literal="true" /><node id="F" start="1060" length="288" literal="true" /><node id="G" start="1348" length="25" literal="true" /><node id="H" start="1373" length="13" literal="true" /><node id="I" start="1386" length="202" literal="true" /></file></map>

The html is largely preserved, but with what seems to be almost random insertions of tags.

I suppose it's worth noting that the view is currently static, and no data from the model is being used. I'm going to try a real implementation of this, that actually uses the model and the Razor engine, but I still would really love to understand what's happening here...

Was it helpful?

Solution

I was able to solve the problem by moving the CSS class definitions from the partial view to the Site.css file. Apparently the Razor engine does not like CSS inside of partial views.

OTHER TIPS

Try to change the action so it returns ready html, not partial view result:

public ActionResult Get()
{
    return Content(RenderRazorViewToString("Get"));
}

public string RenderRazorViewToString(string viewName)
{
    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();
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top