CSHTML file outside Views folder - asp.net

I have an ASP.NET MVC project and I want to put CSHTML files outside of Views Folder. While I can do so easily by adding the CSHTML files in my desired folder, I am not able to render partial view result from these files.
The folder structure I currently have is roughly as follows:
Root
|
|--Templates
| |---Welcome.cshtml
|
|--Views
| |---
I'm using the below syntax from one of the controller actions
public ActionResult Welcome()
{
return PartialView("Welcome");
}
However, doing so, razor is not able to locate the Welcome.cshtml. I have read about using a custom view engine to change the default search location etc. etc. but wondering if this just can be solved by addition configuration.

You can specify the root-relative path when returning a View/PartialView. For example:
public PartialViewResult Welcome()
{
return PartialView("~/Templates/Welcome.cshtml");
}

Related

ASP.NET MVC: When should I create custom View Engine

I know what View Engine is, I preferred to use Razor view engine just because of its simple syntax over ASPX engine. Inbuilt view engine performs almost all task for you, then in what scenario I should create my own view engine,
I googled it but getting answers for How to create it and not when and why to create it.
Can any one help me to describe the real time scenario?
For example, you can change the view files locations that Razor searches with the help of custom view engine.
Normally, in MVC these locations are searched for partial views:
// Part of the RazorViewEngine implementation from the Asp.net MVC source code
PartialViewLocationFormats = new[]
{
"~/Views/{1}/{0}.cshtml",
"~/Views/{1}/{0}.vbhtml",
"~/Views/Shared/{0}.cshtml",
"~/Views/Shared/{0}.vbhtml"
};
Then add for example LayoutsPartialViews folder to Shared folder and add partial views which for example will be used only for layouts. And add for example ColorfuleHeader.cshtml to that location. And try to render that view via this:
#Html.Partial("ColorfulHeader");
Such exception will be throwned:
The partial view 'ColorfulHeader' was not found or no view engine
supports the searched locations. The following locations were
searched...:
So we must add this location to the searched locations. And for doing this we must create our custom view engine:
public class CustomLocationViewEngine : RazorViewEngine
{
public CustomLocationViewEngine()
{
PartialViewLocationFormats = new[] {
"~/Views/{1}/{0}.cshtml",
"~/Views/{1}/{0}.vbhtml",
"~/Views/Shared/{0}.cshtml",
"~/Views/Shared/{0}.vbhtml",
"~/Views/Shared/LayoutsPartialViews/{0}.cshtml",
"~/Views/Shared/LayoutsPartialViews/{0}.vbhtml",
};
}
}
Also, remember that the action invoker goes to each view engine in turn to see if a view can be found. By
the time that we are able to add our view to the collection, it will already contain the standard Razor View
Engine. To avoid competing with that implementation, we call the Clear method to remove any other
view engines that may have been registered, and then call the Add method to register our custom
implementation.
ViewEngines.Engines.Clear();
ViewEngines.Engines.Add(new CustomLocationViewEngine());

Equivalent to Razor Section Helper In Sitecore

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()

Using Html instead of csHtml

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.

URL for new views in MVC4

I've seen several MVC4 tutorials that show how to access the index URL for a view, but I can't seem to reach a new view that I add.
I can access my home index at:
http://localhost:3214/
But if I create a new view (let's call it "NewView.cshtml") I can't access it from
http://localhost:3214/NewView.cshtml
Where would it be?
The page inspector expects the page to be at:
http://localhost:4244/Home/NewView
But it isn't there.
UPDATE:
In the solution explorer the file is located at:
MyProject/Views/Home/NewView.cshtml
OK - So think of your Views as merely html files (although they are not) - i.e. they are purely for display purposes. But they are not static like normal HTMLs - they have code.
Hence its the controller and the route that you need to understand.
The route is what you type in the browser. For instance /Home/NewView will be translated to HomeController, NewView action if thats how you have configured it. The default view is {controller}/{action}/{id} so try http://localhost:4244/Home/NewView/1
Now to properly display and code NewView you need to go to your HomeController and add a NewView action. Like:
public ActionResult NewView()
{
return View(); // This will automatically display the NewView.chtml view from the Home (or Shared) folder in your Views folder
}
Then go to your Routes (typically in your global.asax file and add it like:
routes.MapRoute(
"SomeUniqueRouteName",
"Home/NewView",
new { controller = "Home" action = "NewView" }
);
Then you can call it like http://localhost:4244/Home/NewView without the id cause you haev specified a route for it.
Let me know if you need any more help.

How to Rename my asp.net web page

I have a page name with XYZ.aspx
Now I want to change ABC.aspx how should I do it?
When i directly change it from solution explorer it gives me an error.
Can anyone help me on this?
Thank You
Smartdev
ASP.NET files are usually composed of 1-3 files total depending on the type of project and the file itself. That being said, there is always the markup *.aspx file, then optionally there will be a code-behind *.aspx.cs file and an additional and also optional designer file *.aspx.designer.cs. If you are renaming the file you will need to update code in various places based on the structure of the file itself.
In the event of more than 1 file making up your ASP.NET page you will want to update the .aspx file's header like so:
<%#Page CodeBehind="XYZ.aspx.cs" Inherits="XYZ" %>
to
<%#Page CodeBehind="ABC.aspx.cs" Inherits="ABC" %>
Then in the code behind file
public partial class XYZ : Page { }
to
public partial class ABC : Page { }
Finally, if there is also a *.designer.cs file you will want to update it as well:
public partial class XYZ : Page { }
to
public partial class ABC : Page { }
That should cover all of the files!
To change the name of an aspx file (I'm using vs2012) and associated files single click on filename in solution explorer and single click again to select the name of the file, change the name and enter... vs will rename the code behind file and designer file automatically and change the tags linking them. As nathan above said it does not rename the c# in the code behind to reflect the filename (which would be good practice)... nor importantly does it do a solution wide search for links and more oblique code references to the file. So it's best to do a manual find in files over the entire solution to check and all naming conventions are good.
That should do it

Resources