4

I have my views setup to pre-compile, and therefore, at runtime if I were to try and read the view file (e.g. "~\Views\User\Report.cshtml") I'd get the following dummy-text, as opposed to the contents of my view:

This is a marker file generated by the precompilation tool, and should not be deleted!

Problem is, I'd like to re-use the cshtml view, and rerender it another way at runtime, but I cannot due to the above restriction.

The scenario:

An admin can see a list of users in a /User/Report route. It outputs some HTML that has a list of all users, and their information in an HTML table. These admins frequently want to download this html file (styles and all) to email it as an attachment to someone else. They could, of course, go to File->Save in their browser, but I wanted to simplify that action by adding a link to the page "Download this report as HTML" that would simply return the same page's content, as a forced-downloaded HTML file (2012-07-11_UserReport.html).

So, what I tried to do was re-render the view by running the Report.cshtml file's contents through ASP.NET's File() method, like this:

var html = System.IO.File.ReadAllText(Server.MapPath(@"~\Views\User\Report.cshtml"));
var bytes = System.Text.Encoding.UTF8.GetBytes(html);

return File(bytes,"text/html",string.Format("{0}_UserReport.html",DateTime.Now.ToString("yyyy-MM-dd")));

But, like I mentioned earlier, the file comes back as the dummy-text, not the view, since I'm pre-compiling the views.

I understand that to get around the pre-compilition, I could simply copy the Report.cshtml file, and rename it to Report.uncompiled (adding it to the csproj as of course) and read the contents of it, that's an ok solution, but not good enough.

What I would really like to know is: Is there a way I can get at that pre-compiled content? I looked in the Assembly's embedded resources, and they are not there. Any ideas/suggestions?

Updated with current solution

So after searching around some more, and trying to use WebClient/WebRequest to just make a request to the route's URL and send the response back down to the user to download while at the same time trying to pass the user's .ASPXAUTH cookie (that made WebClient/WebRequest time out for some reason? I even tried to create a new ticket, same result) I ended up going with what I didn't want to do: duplicate the view file, and rename it so it's not precompiled.

The view file (Report.uncompiled) had to be modified a bit as it was, and then I ran it through RazorEngine's Razor.Parse method and got what I needed, but it just felt hackey. Would still like a way to access the view file (Report.cshtml) even after it's compiled.

var templateHtml = Razor.Parse(System.IO.File.ReadAllText(Server.MapPath(@"~\Views\User\Report.uncompiled")),model);
var bytes        = System.Text.Encoding.UTF8.GetBytes(templateHtml);

return File(bytes, "text/html", string.Format("{0}_UserReport.html", DateTime.Now.ToString("yyyy-MM-dd")));
4

1 回答 1

0

WebClient 类会起作用吗?

using System.Net;

using (WebClient client = new WebClient ()) 
{
    client.DownloadFile("http://yourwebsite.com/test.html", @"C:\directory.html");
    // If you just want access to the html, see below
    string html = client.DownloadString("http://yourwebsite.com/test.html");
}

每当您的用户单击一个按钮时就触发此事件,然后它将页面的当前内容保存在哪里?您可能还可以有一个目录选择器,并将他们选择的任何内容输入第二个参数。

它本质上与浏览器保存的功能相同,如果这是您想要的。

于 2012-07-11T22:32:11.610 回答