This is a C# code snippet so there are no tags to escape, all the tags you see are real markup, purely for structural purposes.
Then instead of mixing HTML in with C#, just use the HTML tags created specifically for this (pre + code) and everything should be shown precisely as you've copied it (though I'm not sure what happens with tabs made of other-than-8-spaces, but whitespace (and newlines) in general are supposed to be preserved).
You should say which version of Firefox since it is indeed known to make large changes to code when rendering...
for example there's a nice example (in 3.6.x) where HTML5's "new" anchors-can-wrap-blocks idea makes FF puke depending on what's inside:
In HTML4/XHTML1 this is illegal but HTML5 people chose this over "hrefs-on-everything" because that's not backwards-compatible. Making "a" have the same state as "del" and "ins" (blocks or inlines depending on context) seemed easier to implement. Browsers are, after all, used to seeing anchors wrapped around blocks, since so many people do it, so most browsers have error rendering anyway for this. When unified error rendering for HMTL5 was written, they could easily make new rules over what happens when anchors surround a block.
But if Firefox sees
<a href="foo"> text text
and no </a> anywhere
then it will create new opening anchors... many many many of them. I guess it's an attempt to find the closing one further on?
Well it'll do this if the thing the anchor wraps is one of those fancy new HTML5 elements... prolly because, 3.6.x doesn't have an HTML5 parser so it really doesn't know what those elements actually are, even though in CSS we've set them to display: block.
<div> blah blah... </div>
Firefox starts whipping out the "make new anchor tags" machine. Many many anchor tags.
So I can see Firefox doing what ChronicleMaster described too even if Robert doesn't see it... may depend on the FF version. It also makes me suspect that somehow there really is a mismatch, just once, somewhere, since that's usually what triggers FF (or anyone else even if all other browsers are doing it correctly now) to really mess with markup... its error rendering has been turned on.
I also know that Firefox manipulates your (X)HTML, I've seen the difference between Firefox's page source view and the inspect element view.
You notice how <br /> was turned into <br>. So you're sending this as HTML. I would be super curious to know what FF did if you just sent this page out as application/xhtml+xml just for the lawlz. The error rendering shouldn't be able to kick in: either there's an error and it dies horribly, or there isn't and it doesn't change anything markup-wise. Maybe in Firebug or View Generated Source all tags with closing slashes that technically shouldn't have closing slashes (what every browser getting served "HTML" considers an error and silently ignores) are attempted to recreate "validly" or something.
But I would avoid all the gedoe and just use pre and code tags, which everyone should accept.
Or was there a good reason not to, and instead mix markup in the C# code?