Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP.NET MVC 4 and Razor 2: View engine no longer supports xml?

We had a view (.cshtml) which rendered XML for an RSS feed using ASP.NET MVC 3, which worked fine. Now that we have upgraded to ASP.NET MVC 4 with Razor 2 it's generating compile errors, similar to the below.

Parser Error

Description: An error occurred during the parsing of a resource required to service this request. Please review the following specific parse error details and modify your source file appropriately.

Parser Error Message: Encountered end tag "item" with no matching start tag.  Are your start/end tags properly balanced?

The tags are properly balanced.

Anyone have any thoughts?

UPDATE: I've isolated it down the the link element within the item element within the @foreach (...) { ... } block.

@foreach (var item in Model.Items)
{
<item>
    <title>@item.Title</title>
    <link>@item.Link</link>
    <description>@item.Description</description>
    <guid>@item.Guid</guid>
    @if (item.PublishedDateUtc.HasValue)
    {
    <pubDate>@item.PublishedDateUtc.Value.ToString("ddd, dd MMM yyyy HH:mm:ss") GMT</pubDate>
    }  
</item>      
}

I fixed it by doing using @Html.Raw the below.

@foreach (var item in Model.Items)
{
<item>
    <title>@item.Title</title>
    @Html.Raw(string.Format("<link>{0}</link>", item.Link.ToHtmlEncoded()))
    <description>@item.Description</description>
    <guid>@item.Guid</guid>
    @if (item.PublishedDateUtc.HasValue)
    {
    <pubDate>@item.PublishedDateUtc.Value.ToString("ddd, dd MMM yyyy HH:mm:ss") GMT</pubDate>
    }  
</item>      
}

Anyone have any better suggestions? Obviously, I could just use a class to declare model and return the XML directly from the controller, but I'm more interested in why this behavior occurs and what I can do to conform better to the Razor syntax.

like image 759
Richard Adleta Avatar asked Jun 07 '12 12:06

Richard Adleta


People also ask

Which of the following are valid extensions for Razor view?

The Razor syntax consists of Razor markup, C#, and HTML. Files containing Razor generally have a . cshtml file extension.

What is Razor View Engine in MVC?

Razor is a markup syntax that lets you embed server-based code into web pages using C# and VB.Net. It is not a programming language. It is a server side markup language. Razor has no ties to ASP.NET MVC because Razor is a general-purpose templating engine. You can use it anywhere to generate output like HTML.

What is the difference between Razor view and Razor page?

The difference between them is that View Pages are Razor views that are used to provide the HTML representations (aka views) for services in much the same way View Pages work for MVC Controllers.


1 Answers

When I first glanced at this I noticed your link tag had a closing tag instead of self closing. Razor is smart enough to know html and knows how the link tag is closed. Here is another example of something that could break to show how Razor reads html.

....
<tbody>
    @if (alternating) {
        <tr class='alternating'>
    } else {
        <tr>
    }

    ....

        </tr>
</tbody>

This will fail because it sees a </tr> without an opening tag.

Tags that are always self closing are interpreted by Razor to be self closing. so your link tag actually ended at the >. (since it's valid html to have a self closing tag without a />) So now we come across a closing tag with no opening tag to justify it so the parser gives up and says that it's not properly formatted. I'd have to do some checking but I'm pretty sure it assumes the closing link tag was meant for the item tag since that would give proper balance which is why the rest of the file parses fine until it comes across this lone item tag with no opening tag.

It should be smart enough to know that the previous closing tag wasn't the right one. It might be an issue to take up with the team.

I haven't tried it but you should be able to do this

@foreach (var item in Model.Items)
{
<item>
    <title>@item.Title</title>
    @:<link>
        @item.Link
    @:</link>
    <description>@item.Description</description>
    <guid>@item.Guid</guid>
    @if (item.PublishedDateUtc.HasValue)
    {
    <pubDate>@item.PublishedDateUtc.Value.ToString("ddd, dd MMM yyyy HH:mm:ss") GMT</pubDate>
    }  
</item>      
}
like image 72
Buildstarted Avatar answered Sep 28 '22 07:09

Buildstarted