MVCSiteMapProvider won't use Razor Templates for Menu - c#

I'm enjoying using the well-made MVCSiteMapProvider through Nuget at the moment but I've hit a roadblock.
I'm trying to modify the template for the #Html.MvcSiteMap().Menu() helper. The file I'm modifying is ..\Views\Shared\DisplayTemplates\MenuHelperModel.cshtml and no matter what change I make to the file, the template does not update when rendered.
I've done a Find All with notepad++ and found that within MvcSiteMapProvider.dll there is two templates, one for classic asp.net and one for Razor. So clearly the template within the .dll file is being called - but how do I make this not the case?
It may be worth knowing that although the templates are located in ..\Views\Shared\DisplayTemplates\, the site is configured to use a different folder for Views.
edit: also if I pass in a template name to the helper, still no effect.

Templated helpers are an MVC creation, not one of MvcSiteMapProvider. I strongly suspect your issue is due to reconfiguring your Views folder. MVC does not support a way to reconfigure your templates folder.
But as pointed out in the accepted answer, it is possible to put them under ~/Views/CurrentController/DisplayTemplates/. You might be able to use that feature to put the templates in your newly configured folders. This means that you would need to add a copy of the templates for every single controller, though.
The best solution is not to change the MVC folders from their defaults.
If that is not an option, you might consider rolling your own Menu HTML helper based on the code from the current one that returns an HtmlString rather than using templates.
The templated helpers are better because you can edit the code after it is deployed (which is why we did it that way), but it comes with the caveat that you have to rely on MVC's default folder structure to use them.

Related

Net Core 2 / Razor - theming(views, not css only)

I am looking for solution which would allow me to serve different templates depends on what is set in session (middleware will set it based on the domain).
What I al looking for is that when the theme is set up, when some view suppose to be rendered, mvc would render the view from particular theme.
How can I do that with net core 2,mvc and razor? It would be great if adding theme wouldn't require recompilation (e.g. similar to Wordpress - upload zip file with all required files).
I really have no idea where to start...
I was trying to Google some solutions but I found only one which is outdated totally.
Basically, you just need to customize the list of directories that Razor searches for views. By default, those are Views\{controller} and Views\Shared. You just need to make it so those are instead (or maybe as well as, to have fallback to a "base" theme if a particular theme chooses not to provide a view) {theme}\Views\{controller} and {theme}\Views\Shared, or something similar.
Unfortunately, the documentation doesn't provide much support here. All you get is:
You can customize the default convention for how views are located within the app by using a custom IViewLocationExpander.
As the name implies, that's an interface that Razor uses to get a list of locations to search for views in. In other words, you'd simply need to create your own implementation and then inject that. Something like LanguageViewLocationExpander should give you an idea of what you need to do, since the basic principle at play is the same. It's used for localization and provides the ability to have views nested under language specific-folders.

ASP.Net MVC HTMLHelper with external HTML

I saw some Tutorials on ASP.Net MVC HtmlHelpers and they always included the HTML directly into the SourceCode.
I want to create reusable Controls so that I don't have to write a Login view and the parts of it over and over again over the next projects.
The best thing would be if I could write a DLL and place all my created user controls therein
Some time ago I wrote an application with AngularJS and there were directives
and in them was a templateUrl. Is there something similar in Asp.Net MVC ?
I am using the Razor View Engine and the .Net Framework 4.0.
I know I could use partial views but partial views seem to not work in dlls
"The best thing would be if I could write a DLL and place all my created user controls therein" - You can. There is one little cheat which makes it all work really easily.
When you are writing your html helpers, make sure that you change the namespace to System.Web.Mvc.Html.
If you use the TagBuilder class then you shouldn't be using too much html in your C# code.
Then if you reference your dll in the project, you should be able to access the html helper from your razor view
You can use other namespaces, but you have to have to edit the web.config file inside the Views folder and add a reference to the namespace in the <system.web.webPages.razor> section. By re-using the already referenced namespace, you can save yourself some configuration hassles.
Depending on how many projects and how many developers you want to share the code between, you could also consider a build server product (My team used TeamCity for about 2 years before we needed to pay for a licence). You can then produce your own custom NuGet packages, which lets you share (and manage updates) for partial views, editor templates, html helpers and much more.

Can I override views in Web Forms like I can in MVC?

In ASP.NET MVC I can typically override view e.g. by putting a view with the same name in the DisplayTemplates folder. If I wanted to override the way images are rendered, I could put something like Images.cshtml in the folder.
Now, I want to override the way xforms are rendered in EPiServer. I know how to do this in ASP.NET MVC, but this project uses Webforms.
I have tried to search, but the documentation seems sparse on the subject. In ASP.NET MVC, I could e.g. extend the search engine to search specific locations to look for my views, or put them where ASP.NET looks by default.
This doesn't seem to work in Web Forms. Does anyone know how?
EDIT: EPiServer has an .ascx file which it uses to render an XForm with. I want to tell ASP.NET to use my .ascx file instead. To do this I need to tell ASP.NET to look for my .ascx file, e.g. by telling the ASP.NET view engine to look for my .ascx in a specific folder, or by placing it somewhere the view engine looks by default.
How do I do this?
If you want to replace it everywhere just replace the ascx file. Otherwise I am afraid the answer is no. Web Forms does not look for alternative locations for files by default as controls are usually specified using the full path or the class name. What you want to do would be equivalent of C# looking for alternative namespaces when it cannot find a class name. There are ways to achieve this behavior in Web Forms like for example Dynamic Data but ascx controls is not this.
If you are using the Property web control to display the value you can create your own custom PropertyControl and register it for your type in the PropertyControlFactory. This way you can control how your property will be rendered.
While this doesn't allow you to point out your .ascx directly, you can load it in your server control if you prefer that.
For code examples and a great summary of this (and some other) ways of customizing property rendering in EPiServer, see Mathias Kunto's blog post at http://blog.mathiaskunto.com/2012/03/05/being-friends-with-the-propertycontrolclassfactory-or-101-ways-to-change-episerver-built-in-property-appearances/.

Can I have a folder in my ASP.NET MVC4 project that is a webforms project?

I tried googling, I promise! I may not be asking the question the right way. We have an existing project that is webforms (.NET 3.5 I think). It's not really a VS solution, just a folder with this structure:
/
../App_Code
../bin
../pages
../global.asax
../this.html
../that.aspx
../web.config
In the "pages" folder is where we have a big ugly mess of .aspx pages and there code behind.
App_Code holds some helper classes and whatnot. They rest should be self explanatory.
Questions:
What is the best strategy to put this mess inside an mvc4 application?
What do I have to do with routing back and forth (i.e. from .cshtml pages to .aspx and back again)
Any other considerations?
Yes, you can do it. I would recommend adding this to your routeConfig:
routes.IgnoreRoute("pages/{*pathInfo}");
It may not be even absolutely necessary, but it'll keep the request from even attempting to be parsed out in the routecollection. Just incase you have a page and a route rule that can collide. We do this for our webservices which reside in our MVC 4 application (inherited from an older website project).
That will just work.
You can mix and match any kind of ASP.Net stuff in one project.
The ASPX files will be accessible using their actual paths, just like pure WebForms project.
You can also call MapPageRoute() to apply routing to those files.

Deploying Multiple Sites on the Same Codebase - Asp.Net, C#, MVC

I recently inherited a solution with about 10 projects in it. 6 of these projects are individual websites that are basically copy/pastes of the original.
This means that any changes that need to be made must be made to each project in order to update all the websites.
What I want to do is have one project for the website code and be able to deploy that code and some configuration settings to create a new website. That way when I make updates to the main Web project I can just deploy to all the websites.
How do people normally approach this? I'll outline my thoughts on it and hopefully some of you can point out better ways to accomplish this or at least give me some affirmation that I am on the right track.
Have a master markup with very general containers.
Allow the users/people setting up the site add widgets to the site which will be assigned to widget placeholders at the top and bottom of all the generic containers.
All styling and colors will be controlled with a stylesheet that can be swapped out.
I know there is some kind of theming you can do. Does this just swap out groups of css and let you configure which one to use in the webconfig?
For elements that will be the same across all sites such as footer images have a naming convention. So if I want Site A to have some footer image I just replace the footer.jpg in the project when I deploy.
Your approach is good.
You should use master markup
Your web system will be CMS
You can use themes to define styles of different projects or you can link css files dynamically
if they are really copies of each other than you can make it very general by defining all of them as one website and put all the settings of css images markups in database
If you don't want to make everything very generic you can make web user controls and load them dynamically at run time according to the project (Remember, you can load WebUserControls at runtime using the LoadControl method)
That's unfortunately a question that is likely to get the response 'It depends' as each of those approaches could be used or not used dependent on the needs of the project. If the projects only vary by presentation then master pages combined with CSS would make a reasonable solution.

Categories