3

For one project, we've to generate static .html pages, which are gonna to be published on the same server to serve to millions of visitors.

We've to automate the creation of those files from a c# code, which takes data from a SQL Server database.

The project is already developed using C# asp.net MVC3, and we need to store the dynamically generated pages in .html on the same url to be served to visitors.

I was wondering how to use asp.net MVC3/Razor to generate those .html pages?

I don't want/need to use web caching, for a lot of reasons(load(millions of pages loaded every day), these static pages will be cached on CDN network to further serve super fast without original server going into picture, number of pages are really too many (caching will only help me if I've the same pages a lot of time, but I will have more than million pages visited very frequently, so I will have to generate them often.)

So I really search something to generate HTML pages.

Any idea how to do this...

Krunal
  • 2,967
  • 8
  • 45
  • 101
  • 2
    you say you don't want caching... and in the very next sentence, you say that is exactly what you are going to do. – Andrew Barber Jul 08 '12 at 11:42
  • 1
    we're already using caching and it performs well, but the site traffic we're anticipating is very very high compared to what we currently have and storing html is the simplest way to scale, otherwise we might end up implementing web farm, memcached and all those sort of techniques to support web traffic.. also making application more complex to support distributed cache, and sessions, etc. Storing html is easy compared to them, and they can be cached at CDN as well freeing our main server. – Krunal Jul 08 '12 at 12:41
  • possible duplicate of [Use razor/asp.net mvc3 to generate static html pages?](http://stackoverflow.com/questions/11188173/use-razor-asp-net-mvc3-to-generate-static-html-pages) – Chris Nielsen Jan 10 '13 at 02:57

4 Answers4

2

To start with, make sure your routes all produce urls that can be duplicated as static html files. So that your calls to Html.ActionLink will produce urls you can use.

Generate your whole site as if you are using it directly, and then let it be cached externally.

You could use something like wget on Linux to grab the whole html tree of the site, and put those up along with the content files; css, images, javascript, etc.

Then redownload the site when there are changes.

Andrew Barber
  • 39,603
  • 20
  • 94
  • 123
  • how to generate and store it? – Krunal Jul 08 '12 at 13:00
  • 1
    The first half of your answer is exactly what I was thinking. I would love to have a way to use ASP.Net/MVC/Razor to create a static html site but there's a fundamental problem that MVC is going to give you URLs that won't work for a static site so you'd have to modify all the internal links to use pages instead of routes. You'd have to be very careful when building your routes to make the URLs work when converted to pages. Of course you'd need to avoid having any URLs that use querystrings for anything but possible client-side parsing. I'd love to see a .Net version of DocPad. – Steve Hiner Apr 04 '13 at 17:19
2

In my company we've done something similar. We have a separate program that goes trhough a list of urls, sends a http-request against them. Saves the result and copies it out to the web servers. This way we only have one web server with asp-code on it internally on the network and the servers on the internet has static copies of the dynamic pages. And we get some great performance out of it.

In order for you to get the list of urls you would probably have to create a special view/controller that queries the database for the keys that can be used to query the info you want. So if you have for example a site that shows hamburgers, your list view that creates the urls might query your burger-table and create a bunch of /myburger?name=Wopper type urls. Then your batch-program reads those urls and as described before, does a http-request and saves the result etc.

Smetad Anarkist
  • 898
  • 9
  • 19
  • can you give us idea, how to first generate html using c# for a website built upon c# mvc3? – Krunal Jul 08 '12 at 12:59
  • In order to get the html all you need is a program that uses System.Net.WebClient and then run the DownloadString method. The trick is to figure out the url you want to download. Perhaps using a sitemap is a good start. https://github.com/maartenba/MvcSiteMapProvider – Smetad Anarkist Jul 08 '12 at 13:20
  • I'm looking at possibility to generate & store html the first time it is accessed, and then serve all subsequent visits from html. And make html expire after 24 hours, so it will then regenerate it automatically. – Krunal Jul 08 '12 at 13:26
1

If you want to generate html based on the mvc views and models, you could use the Razor. I have used it to generate email templates, where we have used the Razor to inject the model into a view. You could generate the html from the views and write them into static html files if that fits your purpose. Refer Razor Engine from NuGet, And you could use it like

var html = Razor.Parse(templateView, model);

If you want more customization on it, May be this tutorial could help you. http://www.west-wind.com/weblog/posts/2012/May/30/Rendering-ASPNET-MVC-Views-to-String

Moble Joseph
  • 647
  • 4
  • 14
  • Hi Joseph, thank you for your answer. The site is already using Razor Engine. I'll be looking into this. Thank you – Krunal Jul 09 '12 at 13:57
0

I always use my own email generating method instead of MvcMailer. First, you should generate a string from your view or partial, then add/remove some html tags, such as <html> etc, if you need... Next write this string into a file, save it as a .html file to your path.

public static string HTMLToString(ControllerContext context, string viewName, object model)
{
    if (string.IsNullOrEmpty(viewName))
        viewName = context.RouteData.GetRequiredString("action");

    var viewData = new ViewDataDictionary(model);

    using (var sw = new StringWriter())
    {
        var viewResult = ViewEngines.Engines.FindPartialView(context, viewName);
        var viewContext = new ViewContext(context, viewResult.View, viewData, new TempDataDictionary(), sw);
        viewResult.View.Render(viewContext, sw);

        return sw.GetStringBuilder().ToString();
    }
}
Mr Lister
  • 45,515
  • 15
  • 108
  • 150
Mehmet Taha Meral
  • 3,315
  • 28
  • 30