35

Is it possible to use server side include in Razor view engine to include .html or .asp file? We have an .html file and .asp files that contain website menus that are used for all of our websitse. Currently we use server side include for all of our sites so that we only need to change the mensu in one place.

I have the following code in the body of my _Layout.cshtml

<body>
<!--#include virtual="/serverside/menus/MainMenu.asp" -->   
<!--#include virtual="/serverside/menus/library_menu.asp" -->
<!--#include virtual="/portfolios/serverside/menus/portfolio_buttons_head.html" -->
@RenderBody()
</body>

Instead of including the content of the file, if I do a view source, I see the literal text.

" <!--#include virtual="/serverside/menus/MainMenu.asp" --> 
    <!--#include virtual="/serverside/menus/library_menu.asp" -->
    <!--#include virtual="/portfolios/serverside/menus/portfolio_buttons_head.html" -->"
atbebtg
  • 4,023
  • 9
  • 37
  • 49

14 Answers14

93
@Html.Raw(File.ReadAllText(Server.MapPath("~/content/somefile.css")))
abatishchev
  • 98,240
  • 88
  • 296
  • 433
Mads Klinkby
  • 939
  • 6
  • 2
  • 2
    @AndrewBarber - can you elaborate? I understand it wouldn't work for the .asp files because no rendering engine would be loaded, but it would work for .html (and other static files), right? – mlhDev Apr 01 '13 at 18:16
  • 5
    Yes this works fine for static files which was part of the question. I had the issue of needing to include an `.svg` file in my page and this has been the easiest solution – dan richardson Jun 14 '13 at 09:28
  • 2
    I know this question is old but your answer was exactly what I was looking for to include an SVG file as HTML on my page! Good work! – ddilsaver Oct 08 '13 at 16:01
62

Try making your html page to a cshtml page and including it with:

@RenderPage("_header.cshtml")
axel22
  • 32,045
  • 9
  • 125
  • 137
Deany WebGeek
  • 641
  • 6
  • 4
  • 3
    this method works for including static pages. use a relative url for the path to the cshtml page. – lamarant Mar 01 '12 at 17:00
  • 5
    This only works if you're including a cshtml page and not a straight html page. – mikesl Jun 06 '12 at 18:16
  • The cshtml page will be cached. You can also configure the cache to be quite aggressive (using `[OutputCache]` attribute and a long lifetime). – jgauffin May 19 '13 at 18:31
  • get this error when i do this `Failed to load resource: the server responded with a status of 403 (Forbidden) ` – PUG Jan 14 '14 at 18:49
8

Try implementing this HTML helper:

public static IHtmlString ServerSideInclude(this HtmlHelper helper, string serverPath)
{
    var filePath = HttpContext.Current.Server.MapPath(serverPath);

    // load from file
    using (var streamReader = File.OpenText(filePath))
    {
        var markup = streamReader.ReadToEnd();
        return new HtmlString(markup);
    }
}

or:

public static IHtmlString ServerSideInclude(this HtmlHelper helper, string serverPath)
{
    var filePath = HttpContext.Current.Server.MapPath(serverPath);

    var markup = File.ReadAllText(filePath);
    return new HtmlString(markup);
}
Joe
  • 122,218
  • 32
  • 205
  • 338
John Hann
  • 927
  • 6
  • 10
5
@RenderPage("PageHeader.cshtml")
<!-- your page body here -->
@RenderPage("PageFooter.cshtml")

This works just fine and can save you a lot of time.

Stacked
  • 6,892
  • 7
  • 57
  • 73
  • This works for me. This only caveat is that you can't use the RenderPage() overloads that pass parameters (model objects) to the sub-pages. The sub pages have to use the same model objects as the parent. – Kent Dec 11 '12 at 23:29
  • get this error when i do this `Failed to load resource: the server responded with a status of 403 (Forbidden) ` – PUG Jan 14 '14 at 18:49
4

Razor does not support server-side includes. The easiest solution would be copying the menu markup into your _Layout.cshtml page.

If you only needed to include .html files you could probably write a custom function that read the file from disk and wrote the output.

However since you also want to include .asp files (that could contain arbitrary server-side code) the above approach won't work. You would have to have a way to execute the .asp file, capture the generated output, and write it out to the response in your cshtml file.

In this case I would go with the copy+paste approach

marcind
  • 52,944
  • 13
  • 125
  • 111
  • Server.Execute - Bad performance but I am guessing that his desperate since he is trying to use classic asp with razor. – John Jun 05 '15 at 09:19
3

Create a HtmlHelper extension method that gets the contents of the files:

public static class HtmlHelpers
{
  public static MvcHtmlString WebPage(this HtmlHelper htmlHelper, string url)
  {
    return MvcHtmlString.Create(new WebClient().DownloadString(url));
  }
}

Usage:

@Html.WebPage("/serverside/menus/MainMenu.asp");
carlsb3rg
  • 752
  • 6
  • 14
  • How does the performance of this compare with an oldfashioned server-side include? – Oskar Austegard Jun 22 '12 at 14:37
  • I don't know enough about the mechanics of the the server-side include. If the rendering engine is smart enough to somehow asynchronously download and inject the contents of the included resource, it might be marginally faster. But I think the actual latency of getting the resource would be much more significant. – carlsb3rg Jun 24 '12 at 10:35
  • Another possibility would be to create a HtmlHelper or partial Razor view with some JQuery, or just put the JQuery directly in your master page and let JQuery download and asynchronously update a div. But if I was in the unfortunate situation of having to do this at all, I would probably stick to my original answer, but add exception handling and cache the results in a dictionary using the url as a key. – carlsb3rg Jun 24 '12 at 10:39
  • you'd probably want to do Server.MapPath(url) to get a full path name and then load the file with File.ReadAllText - rather than using a WebClient – Simon_Weaver Mar 12 '13 at 06:18
  • 2
    this will be a lot slower then creating a csthml page – jgauffin May 19 '13 at 18:30
3

Sorry guys for bit old answer but I found some way to attach asp file with razor. Of course you need to do some trick but it works! First of all I created .NET MVC 3 application.

In my _Layout.cshtml I added following line:

@Html.Partial("InsertHelper")

Then I created InsertHelper.aspx in my Shared folder with this content:

<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage" %>

<!--#include VIRTUAL="/ViewPage1.aspx"-->

ViewPage1.aspx is locaited in my root directory, and has just simple if to check whether it works:

<%
string dummy;
dummy="nz";
%>

<% if (dummy == "nz") { %>
nz indeed
<% } else { %>
not nz
<% } %>

And it works!

Razor is able to render partials with different ViewEngine, and that's why this example is working.

And one more thing: remember to not add following line in both aspx files:

<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage" %>

You can add it only once! Hope it helps!

Karol
  • 7,803
  • 9
  • 49
  • 67
2

I had the same issue when I tried to include an .inc file in MVC 4.

To solved this issue, I changed the suffix of the file to .cshtml and I added the following line

@RenderPage("../../Includes/global-banner_v4.cshtml")
Andrew Barber
  • 39,603
  • 20
  • 94
  • 123
  • get this error when i do this `Failed to load resource: the server responded with a status of 403 (Forbidden) ` – PUG Jan 14 '14 at 18:50
2

In my _Layout.cshtml I added following line:

@Html.Partial("InsertHelper")

Then I created InsertHelper.aspx in my Shared folder with this content:

<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage" %>

<!--#include VIRTUAL="/ViewPage1.aspx"-->
Mariusz Jamro
  • 30,615
  • 24
  • 120
  • 162
Rolwin Crasta
  • 4,219
  • 3
  • 35
  • 45
2

Just do:

@Html.Partial("_SliderPartial")

while "_SliderPartial" is your "_SliderPartial.cshtml" file and your fine.

nova.cp
  • 455
  • 1
  • 9
  • 22
1

Html.Include(relativeVirtualPath) Extension Method

I wanted to include files like this for documentation purposes (putting the contents of a file in a <pre> tag).

To do this I added an HtmlHelperExtension with a method that takes a relative virtual path (doesn't have to be an absolute virtual path) and an optional boolean to indicate whether you wish to html encode the contents, which by default my method does since I'm using it primarily for showing code.

The real key to getting this code to work was using the VirtualPathUtility as well as the WebPageBase. Sample:

// Assume we are dealing with Razor as WebPageBase is the base page for razor.
// Making this assumption we can get the virtual path of the view currently
// executing (will return partial view virtual path or primary view virtual
// path just depending on what is executing).
var virtualDirectory = VirtualPathUtility.GetDirectory(
   ((WebPageBase)htmlHelper.ViewDataContainer).VirtualPath);

Full HtmlHelperExtension Code:

public static class HtmlHelperExtensions
{
    private static readonly IEnumerable<string> IncludeFileSupportedExtensions = new String[]
    {
        ".resource",
        ".cshtml",
        ".vbhtml",
    };

    public static IHtmlString IncludeFile(
       this HtmlHelper htmlHelper, 
       string virtualFilePath, 
       bool htmlEncode = true)
    {
        var virtualDirectory = VirtualPathUtility.GetDirectory(
            ((WebPageBase)htmlHelper.ViewDataContainer).VirtualPath);
        var fullVirtualPath = VirtualPathUtility.Combine(
            virtualDirectory, virtualFilePath);
        var filePath = htmlHelper.ViewContext.HttpContext.Server.MapPath(
            fullVirtualPath);

        if (File.Exists(filePath))
        {
            return GetHtmlString(File.ReadAllText(filePath), htmlEncode);
        }
        foreach (var includeFileExtension in IncludeFileSupportedExtensions)
        {
            var filePathWithExtension = filePath + includeFileExtension;
            if (File.Exists(filePathWithExtension))
            {
                return GetHtmlString(File.ReadAllText(filePathWithExtension), htmlEncode);
            }
        }
        throw new ArgumentException(string.Format(
@"Could not find path for ""{0}"".
Virtual Directory: ""{1}""
Full Virtual Path: ""{2}""
File Path: ""{3}""",
                    virtualFilePath, virtualDirectory, fullVirtualPath, filePath));
    }

    private static IHtmlString GetHtmlString(string str, bool htmlEncode)
    {
        return htmlEncode
            ? new HtmlString(HttpUtility.HtmlEncode(str))
            : new HtmlString(str);
    }
}
Sam
  • 26,946
  • 12
  • 75
  • 101
1

you can include server side code and aspx file in .cshtml files as below and then inlude classic asp files or html files. Here are the steps

  1. Index.cshtml
@Html.RenderPartial("InsertASPCodeHelper")

2.InsertASPCodeHelper.aspx

<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage<dynamic>" %>
<!--#include VIRTUAL="~/Views/Shared/Header.aspx"-->
  1. Header.aspx
<!--#include file="/header/header.inc"-->
1

Why not include a section within your _Layout.cshtml page that will allow you to render sections based on what menu you want to use.

_Layout.cshtml

<!-- Some stuff. -->
@RenderSection("BannerContent")
<!-- Some other stuff -->

Then, in any page that uses that layout, you will have something like this:

@section BannerContent 
{
  @*Place your ASP.NET and HTML within this section to create/render your menus.*@
}
JasCav
  • 34,458
  • 20
  • 113
  • 170
0

Using includes is not the correct way to use menus with mvc. You should be using a shared layout and/or partial views.

However if for some odd reason, you must include an html file, here is a way to do it.

Helpers/HtmlHelperExtensions.cs

using System.Web;
using System.Web.Mvc;
using System.Net;

namespace MvcHtmlHelpers
{
    public static class HtmlHelperExtensions
    {
        public static MvcHtmlString WebPage(this HtmlHelper htmlHelper, string serverPath)
        {
            var filePath = HttpContext.Current.Server.MapPath(serverPath);
            return MvcHtmlString.Create(new WebClient().DownloadString(filePath));
        }
    }
}

Add new namespace to web.config

<pages pageBaseType="System.Web.Mvc.WebViewPage">
  <namespaces>
    <add namespace="MvcHtmlHelpers"/>
  </namespaces>
</pages>

Usage:

@Html.WebPage("/Content/pages/home.html")
mikesl
  • 2,133
  • 20
  • 25