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.