On one of our recent projects, we needed to add a feature to a client’s website that would dynamically generate XML in a Razor CSHTML file.
In order to do this, we first needed to tell razor that we’re writing XML, which we did by quite simply writing code to set Response.ContentType
to XML’s MIME type (text/xml
). We also had to set the layout property to be null, to ensure that no HTML from the master pages is added to the file (of course setting the layout property may not always be necessary, depending on how your site is designed). The XML declaration and content was added below.
However, setting these values was not enough. All of the articles we found on the subject only mention changing Response.ContentType
, but when we tested it after just doing that, we ended up with an XML Parsing error stating “XML or text declaration not at start of entity”.
After testing, we figured out that the reason we got this error is quite simple: the XML declaration statement (<?xml version="1.0" encoding="UTF-8" ?>
) was not at the start of the file (but we did include it). The CSHTML file started writing the XML on the third line. In order for the XML declaration to be valid, it must be at the absolute beginning of the document; not even whitespace can exist before it.
The code block we used to set the content type and layout values was at the top of the file. Because of this, we were creating an extra line break before the declaration. Moving this code to the bottom of the file got rid of this extra line break, but the XML was still starting on the second line, and therefore, still not valid.
To work around this issue, we added a line of code right under the line where we’d set the response content type, using Document.Write
to write out the XML declaration statement. Doing this printed the declaration on the first line of the document, and makes sure we don’t have to worry about accidentally adding extra line breaks to the top of the file.
Now, our final code looks like this:
@{
Layout = null;
Response.ContentType = "text/xml";
Response.Write("<?xml version="1.0" encoding="UTF-8" ?>");
}
Just add that to a CSHTML file, and, there you go, it outputs XML. We just needed to add the XML content below to finish the file.
This is a known bug in the razor engine that they have decided not to fix.
https://aspnetwebstack.codeplex.com/workitem/481
Thanks for this post! However, when trying to add the code you suggested, I ran into issues with the double quotes, also tried escaping the double quotes, using single quotes inside — none of which worked. What did end up working for me was something from the link that Heather posted. Here it is.
@{
Layout = null;
}<?xml version="1.0" encoding="utf-8" ?>