In my view, would like to render the contents of an HTML file as a partial view. It is giving me this error though when I add this to the .cshtml view:
#Html.Partial(Url.Content("~/Test/main.html"))
Errors:
Exception Details: System.InvalidOperationException: The partial view '/Scripts/main.html' was not found or no view engine supports the searched locations. The following locations were searched:
/Scripts/main.html
The file is physically there though. Is there a different way I should be doing this?
You can't use Html.Partial for this.It is a special helper method for rendering Partial Views. Instead you can add an Action like this:
[ChildActionOnly]
public ActionResult GetHtmlPage(string path)
{
return new FilePathResult(path, "text/html");
}
And you can call it from your View with using Html.Action helper Method:
#Html.Action("GetHtmlPage","controllername", new { path = "~/Test/main.html" })
Follow these steps
Create a view in ~/views/shared folder. give it name test.cshtml.
Copy the content of HTML in it.
Use Html.Partial("test") on page to render the html of that view.
I think it's a better solution:
Use WriteFile from the Response object
#Response.WriteFile(pathToMyHtmlFile)
taken from here
The simple answer is to rename the main.html file to main.cshtml which will be recognized by the Razor view engine for rendering.
You could use this in your cshtml view:
#{this.GetOutputWriter().Write(File.ReadAllText(Server.MapPath("/your/static/file.html")));}
A total different way is just load the file in javascript
<div id="loadId">
</div>
<script>
$(document).ready(function () {
$('#loadId').load('filepath');
});
</script>
You can set the filepath in the controller, or put it in the model, if you want, and use:
$('#loadId').load('#ViewBag.filepath');
Just use an ajax request to fetch the html file output the content into your main html. Since it is an html file, it will be cached in subsequent calls and there will be no performance impact.
Related
I have the HTML for a layout page stored in my database rather than in a static file. How can I use this as a layout page to display content in my application?
For example, I'd tried this approach where I could have this static layout page whose body tag looks like this:
<body>
#Html.Action("GetBody", "Layout")
</body>
GetBody could call a controller action to get my page from the database (but in this example just returning text for simplicity):
public ActionResult GetBody()
{
return Content("<div>here's my content: <br /> #RenderBody()</div>", "text/html");
}
Part of this text would include #RenderBody(), but this renders as text rather than it being the call to the RenderBody method. I appreciate this is the expected behaviour as it's just text, but is there a way to actually render the body here in this way?
I am trying to include different scripts on different pages in Sitecore and can't seem to find a very good way of doing this. In a normal mvc project I could add the #Section{} helper and use that on different partial views to specify where I want those scripts in the layout view, but I haven't been able to find an equivalent for the way that Razor helper is implemented with Sitecore. I'd like to do this without using a place holder, I don't want to add a view in Sitecore every time I need to add a script file.
Thanks in advance.
I'm afraid you're out of luck here.
#Section is not supported because Sitecore doesn't render the Razor views in the same way as MVC does.
A Sitecore MVC layout is basically just a regular view that is rendering several other partial views or controller actions.
So when the placeholders in the <body> of your layout view are being rendered, the <head> section of that layout has already been rendered.
There is no such thing as deferred rendering in Sitecore MVC like you can do with #Section.
Everything in the view is executed from top to bottom, so if you can put your scripts at the end of your layout (like before the </body>), you can still manipulate data in the views or actions that are executed earlier.
The way I have it setup in my current Sitecore MVC solution is my layout has an extension method call to RenderScripts() at the bottom before the closing body tag.
#Html.RenderScripts()
That extension method looks like this:
public static IHtmlString RenderScripts(this HtmlHelper htmlHelper)
{
var templates = (from object key in htmlHelper.ViewContext.HttpContext.Items.Keys
where key.ToString().StartsWith("_script_")
select htmlHelper.ViewContext.HttpContext.Items[key]).OfType<Func<object, HelperResult>>()
.Select(template => template(null)).ToList();
foreach (var template in templates)
{
htmlHelper.ViewContext.Writer.Write(template);
}
return MvcHtmlString.Empty;
}
Then on each MVC Razor View when I want to include a .js file that is specific to that rendering I call something like below at the bottom of the file:
#Html.Script(
#<script src="#Url.Content("~/js/custom/orderdetail.js?t=11172015")" type="text/javascript"></script>
)
Below is the Script extension method:
public static MvcHtmlString Script(this HtmlHelper htmlHelper, Func<object, HelperResult> template)
{
htmlHelper.ViewContext.HttpContext.Items["_script_" + Guid.NewGuid()] = template;
return MvcHtmlString.Empty;
}
This has worked out well for us and I think it is what you are trying to do.
Indeed, the Section-helper isn't supported in Sitecore. If you're using MVC4 you can maybe use Bundles to solve your problem. For more information see: http://www.asp.net/mvc/tutorials/mvc-4/bundling-and-minification
You can also create multiple bundles for specific views. In a single Bundle you can add multiple script and output it in your view by adding #Scripts.Render()
I want to use pure html page instead of cshtml with MVC .net.
But when I add view by right clicking Index i can see only two options.
public class HomeController : Controller
{
//
// GET: /Home/
public ActionResult Index()
{
return View();
}}
Cshtml (Razor)
Aspx
I followed
Can I serve .html files using Razor as if they were .cshtml files without changing the extension of all my pages?
forum but still no help. I still don’t see an option to add html instead of cshtml
I also tried adding html page directly to view folder but i dont know how to point that view from my controller function.
Replacing Index.cshtml with Index.html gave me this error
The view 'Index' or its master was not found or no view engine supports the searched locations. The following locations were searched:
~/Views/Home/Index.aspx
~/Views/Home/Index.ascx
~/Views/Shared/Index.aspx
~/Views/Shared/Index.ascx
~/Views/Home/Index.cshtml
~/Views/Home/Index.vbhtml
~/Views/Shared/Index.cshtml
~/Views/Shared/Index.vbhtml
In order to render plain HTML file you can use
return new FilePathResult(HtmlPath, "text/html");
where HtmlPath is
Server.MapPath(string.Format("~/Views/{0}/{1}.html", YourControllerName, YourHtmlfileName))
You can create a View with a regular cshtml file add it to the controller and in the View itself just use pure html and add the following to the top:
#{
Layout = null;
}
This way you use a cshtml file that doesn't use you master layout file. And just serves whatever html you put in it.
If it's a static html file you don't need to point your controller to it, because IIS can serve them just fine. Add an html file to your project (anywhere but NOT in the viewsfolder), and point your browser to that file.
If you right click on your Content folder you can select 'Add new item...'. You can then select 'Web' in the tree on the left and choose the 'HTML Page' on the right.
This should add you an HTML page.
Add a file. Rename it.
F2 in solution explorer.
I have a layout _Layout.cshtml and in the end of it I have:
...
...
#RenderSection("mySection", required: false)
</body>
</html>
At the end of my view I have:
#section mySection {
...
...
}
My view is using partial views. When I tried to add content to the mySection section - nothing happend. In my partial view:
#section mySection {
....
....
}
The section content from the partial view didn't render. Are sections allowed in PartialViews? if not, why??
Had exactly this issue today but as #AliRıza Adıyahşi quotes #Darin Dimitrov its not possible to access the section of the layout view from a partial view. In my case the solution was to simply have the script on the layout page.
From my experience I have found it is easier to have one JS file that is minified rather than have inline scripts. Can even have seperate files to make dev more easy and then batch file them together with minify on deploy.
I have a partial view (.ascx) that should include its own CSS file as it's used in multiple other views. How do I inject a stylesheet in the page server-side, i.e. without using JavaScript?
Dario - due to using this for partialviews, you're going to always have the problem that the <head> section of the document is already in place and therefore can't be modified. If you want to remain WC3 compliant, then you'll have to put any further css into the head section via javascript. This may or may not be desirable (if you've got to cater for downsteam browsers with javascript turned off).
the main problem that you may be aluding to is the fact that you can't put <asp:contentplaceholders> into your partials. this is a pain (tho understandable as the masterpage ref would tie the partial too closely to a particular master page).
To this end, I've created a little helper method that does the basic grunt work to put the css file into the head section automatically.
edit - (as per Omu's js suggestion) this is a nice little halfway house:
// standard method - renders as defined in as(cp)x file
public static string Css(this HtmlHelper html, string path)
{
return html.Css(path, false);
}
// override - to allow javascript to put css in head
public static string Css(this HtmlHelper html, string path, bool renderAsAjax)
{
var filePath = VirtualPathUtility.ToAbsolute(path);
HttpContextBase context = html.ViewContext.HttpContext;
// don't add the file if it's already there
if (context.Items.Contains(filePath))
return "";
// otherwise, add it to the context and put on page
// this of course only works for items going in via the current
// request and by this method
context.Items.Add(filePath, filePath);
// js and css function strings
const string jsHead = "<script type='text/javascript'>";
const string jsFoot = "</script>";
const string jsFunctionStt = "$(function(){";
const string jsFunctionEnd = "});";
string linkText = string.Format("<link rel=\"stylesheet\" type=\"text/css\" href=\"{0}\"></link>", filePath);
string jsBody = string.Format("$('head').prepend('{0}');", linkText);
var sb = new StringBuilder();
if (renderAsAjax)
{
// join it all up now
sb.Append(jsHead);
sb.AppendFormat("\r\n\t");
sb.Append(jsFunctionStt);
sb.AppendFormat("\r\n\t\t");
sb.Append(jsBody);
sb.AppendFormat("\r\n\t");
sb.Append(jsFunctionEnd);
sb.AppendFormat("\r\n");
sb.Append(jsFoot);
}
else
{
sb.Append(linkText);
}
return sb.ToString();
}
usage:
<%=Html.Css("~/Content/yourstyle.Css")%>
or:
<%=Html.Css("~/Content/yourstyle.Css", true)%> // or false if you want!!
worth a back-pocket approach if all else fails. it may also be possible to adapt the logic above to hit an actionfilter and add the css to the reponse headers etc.., rather than outputting the js string.
Is there a reason you cannot just put the stylesheet in the main view page? Unless it is extremely large, it should not cause your page to load significantly slower when not being used, especially after compression.
Furthermore, if the partial view is being retrieved by ajax, you will end up re-downloading the css file multiple times (depending on the browser's caching).
I'm not an ASP.NET or MVC expert, but I am currently working on a project with it. Would it be possible to include something like this in the head of your master page?
<asp:ContentPlaceHolder ID="HeadContent" runat="server"></asp:ContentPlaceHolder>
Then somehow get your CSS into the content placeholder?
<asp:Content ID="styleSheetHolder" ContentPlaceHolderID="HeadContent" runat="server">
<link rel='stylesheet' href='yourstyle.css' type='text/css' />
</asp:Content>
It looks like you'd have to do this from the calling page, which would introduce duplication of code. I'm not sure how to get around that. Maybe it could it be done with an HTML helper.
A place I worked had a site with a lot of conditional partial views, which could and would change from time to time as new things were added to the application. The best way we found was to use naming conventions - naming the partial view, stylesheet and script the same (except extension, of course).
We added one or more stylesheets, scripts and partial views to the page's view model. We then used a custom HTML helper to loop through the relevant array in each content section and insert the required content. The pain was having to manage three or more files for each component, but at least we were able to reduce the amount of maintenance in the hosting pages.
Never did resolve the problem of putting a partial view inside a partial view, though.
Why not put the link tag in your partial view:
<link rel="stylesheet" href="yourstyle.css" type="text/css" />