When I generate my controller and views with the below command
scaffold controller <Entity> -force -repository -DbContextType "XXX" -Area YYY
It generates .aspx (web form) pages instead of .cshtml (razor)
How can I change this default behaviour. I think when I first created a new project it asked me to select the default view engine and I picked the wrong one (webforms).
Also are there any free or cheap T4 templates for MVC 3 that generate nicer and more functional views. i.e using webgrid / jQUery etc.
Solution wide scaffolders configuration is stored in scaffolding.config which is located in the same folder with solution file.
On installation stage MvcScaffolding package launches init.ps script (you can find it in <packages folder>\MvcScaffolding.<version>\tools directory). Script counts aspx, cshtml and vbhtml views and based on these numbers decideds what view scaffolder will be used. Here is a piece of this logic:
function InferPreferredViewEngine() {
# Assume you want Razor except if you already have some ASPX views and no Razor ones
if ((CountSolutionFilesByExtension aspx) -eq 0) { return "razor" }
if (((CountSolutionFilesByExtension cshtml) -gt 0) -or ((CountSolutionFilesByExtension vbhtml) -gt 0)) { return "razor" }
return "aspx"
}
# Infer which view engine you're using based on the files in your project
$viewScaffolder = if ([string](InferPreferredViewEngine) -eq 'aspx') { "MvcScaffolding.AspxView" } else { "MvcScaffolding.RazorView" }
Set-DefaultScaffolder -Name View -Scaffolder $viewScaffolder -SolutionWide -DoNotOverwriteExistingSetting
So you can switch view scaffolder using following commands:
Set-DefaultScaffolder -Name View -Scaffolder "MvcScaffolding.RazorView" -SolutionWide
Set-DefaultScaffolder -Name View -Scaffolder "MvcScaffolding.AspxView" -SolutionWide
Or you can manually edit scaffolding.config file and replace value for ScaffolderName attribute in tag:
<Default DefaultName="View" ScaffolderName="put here either MvcScaffolding.RazorView or MvcScaffolding.AspxView" />
Related
I'm working with Joomla 3's MVC 12.1 platform and running into some issues with getting template overrides to work.
My Component has 3 controllers: stores, coupons, sales.
For each of these controllers I call my view similiar to this:
$paths = new SplPriorityQueue;
$paths->insert(JPATH_SITE.'/templates/'.$app->getTemplate().'/html/com_stores/stores', 'normal');
$paths->insert(JPATH_COMPONENT . '/views/stores/tmpl', 'normal');
$view = new StoresViewsStores(new StoresModelsStore, $paths);
$view->setLayout('default');
// Render our view.
echo $view->render();
Only deference between them is switching the view/model/directories out respectively.
As long as I don't include any overrides in my template everything works as expected. However as soon as I include overrides things get wonky.
If I add a com_stores/stores/default.php into my template, my stores get overridden correctly however the coupons and sales controllers start pointing to the stores override instead of their own folders.
Is their something that i'm missing that is making each of the controllers point to the same override?
Just for reference here is what is in for the paths in each controller.
Stores:
$paths->insert(JPATH_SITE.'/templates/'.$app->getTemplate().'/html/com_stores/stores', 'normal');
$paths->insert(JPATH_COMPONENT . '/views/' . $viewName . '/tmpl', 'normal');
Sales:
$paths->insert(JPATH_SITE.'/templates/'.$app->getTemplate().'/html/com_stores/sales', 'normal');
$paths->insert(JPATH_COMPONENT . '/views/' . $viewName . '/tmpl', 'normal');
Coupons:
$paths->insert(JPATH_SITE.'/templates/'.$app->getTemplate().'/html/com_stores/coupons', 'normal');
$paths->insert(JPATH_COMPONENT . '/views/' . $viewName . '/tmpl', 'normal');
Thanks for the help
Finally found the solutions. I started by tracing through The component to see what being loaded. Turns out everything was being forced through my stores controller. So I made a slight change in how my component checks to see which controller to use.
$controller = $app->input->get('controller','stores');
to
$controller = $app->input->get('view','stores');
One thing to note is that all of my views match match my controller name perfectly so i didn't have to do anything special to know this will work.
In MVC 3 I was able to put:
#{
string rootPath = HttpContext.Current.Request.ApplicationPath;
if (rootPath == "/")
{
rootPath = rootPath.Replace("/", "");
}
}
in my _Layout.cshtml file and then use rootPath in any of my other views to get the site root.
I tried the same thing in a MVC 4 app and it doesn't work unless I put the above code in the same view file I'm trying to use rootPath in.
Has anyone else bumped into this issue?
Depending on what you are doing, you can just put that logic in an html helper which can then be called from anywhere.
I'm moving my WebForms project to MVC and having a hard time designing things.
The basic display of my app is in _Layout. The page is divided into 4 parts(say Part A,B,C and D), with 3(A,B,C) just containing html and one(D) is dynamic. I had used #RenderBody to bring in the content of Part D. However, now the other parts are changing and I need separate controllers for these parts. What is the best way to get their contents to be displayed into _Layout?
#Html.RenderPartial / #Html.Partial / #Html.RenderAction / #Html.Action ?
I'm currently trying to replace Part C by using -
#Html.Action("Index", "CController")
However, this is not working.
In Index.cshtml for CController, I've the Layout = null, initially it was set to point to _Layout.cshtml, but I read here that this created issues.
After putting the C Part in CControllers view, it does not event display the basic _Layout page that it displayed earlier.
Here's the Index.cshtml of CController -
<div id="noteContainerDiv">
Here goes all the data to display
</div>
And Here's the code for CController.cs -
public class CController : Controller
{
public ActionResult Index()
{
return PartialView();
}
}
Can anyone suggest the right way to design this?
What you could do is have a view model for your subview (the one you call D) and pass in this view model from your layout view.
I.e. by doing something like this in your _Layout:
#Html.Partial("_SubviewD", Model.SubviewDModel)
Then obviously in your controllers you need to initialize this subview model and include it in your model (or alternatively, in the ViewBag--apologies for suggested being evil!) You could even find ways to do this without changing all your controllers (for example through a base Controller class and overriding OnActionExecuted).
There are many ways you could do this. But I would stick to your initial approach.
Have your CController Index action return a PartialViewResult instead of a full result.
You don't set the layout for partial views. So in your CController index action you'll have something like this:
var model = ....
return this.PartialView("NameOfYourPartialView", yourModel);
And when you call
#Html.Action("Index", "CController")
Everything should be OK, cool?
In my Views root folder I have _ViewStart.cshtml, which has:
#{
Layout = "~/Views/Shared/_Layout.cshtml";
Page.Title = "Using Root ViewStart!";
}
Then in a nested Views\ProjectCharter folder, I have another _ViewStart.cshtml, which looks like this:
#{
Layout = "~/Views/Shared/_ProjectLayout.cshtml";
Page.Title = "Using Nested ViewStart!";
}
(note that both the _Layout.cshtml and the _ProjectLayout.cshtml file are in the same folder, called Views\Shared).
The problem I'm having is that the views in my Views\ProjectCharter folder are NOT using the _ProjectLayout.cshtml Layout...instead they are still using the root _Layout.cshtml (even though they are correctly picking up the "Using Nested ViewStart" title).
What's interesting is that if I change my ActionMethod to return the View using
return View("Create","~/Views/Shared/_ProjectLayout.cshtml",newProjectCharter);
instead of just
return View(newProjectCharter);
then the view does indeed use the _ProjectCharterLayout.cshtml layout. Any idea what I am missing? I don't want to have to change all my ActionMethods to use this more verbose overload.
As I can see from your post you are referring to _ProjectLayout.cshtml being in "
Views\ 'PROJECTCHARTER'
but in the code you are saying that it is in the shared folder:
Layout = "~/Views/ 'SHARED' /_ProjectLayout.cshtml";
Hope that will sort it out
In my MVC project has 2 Areas which is Admin and Client and I need to dynamic config Layout for Client side, In _ViewStart (in client) file will set layout for all of client page.
Layout = "~/Views/Shared/_Layout.cshtml";
So if we need to change client layout we can change Layout path of cshtml file in _ViewStart file right? I cant find how to change inside ViewStart file or Is there another solution in this case.
Thanks for your Help :)
Remember that anything within the #{ ... } is treated as code. So, it should be a simple matter of placing a condition in there to change how it's inherited:
#{
Layout = "~/Views/Shared/_Layout.cshtml";
if (User.Current.IsAuthenticated) {
Layout = "~/Views/Shared/_AdminLayout.cshtml";
}
}
Though you're probaby better off looking at Themes (and have an admin/user theme). Alternatively, you can make your _Layout.cshtml smarter and have it handle the different views based on conditions as well.
See Also: MVC3 Razor - Is there a way to change the Layout depending on browser request?
Your question has not enough information to give you a complete code sample.
But basicly you can do this
if (InsertIsAdminLogicHere) {
Layout = "~/Views/Shared/_AdminLayout.cshtml";
} else {
Layout = "~/Views/Shared/_Layout.cshtml";
}
If you show us how you determine admin or not, we can provide more help.
hope this helps
You can take advantage of Nested Layouts. Create a base controller and drive all controllers from this one.
public class ControllerBase : Controller
{
public ControllerBase()
{
ViewBag.Theme = "~/Views/Shared/Default/Views/_Layout.cshtml";
}
}
public class HomeController : ControllerBase
{
public ActionResult Index()
{
return View();
}
}
_ViewStart.cshtml (don't make any changes in this file)
#{
Layout = "~/Views/Shared/_Layout.cshtml";
}
Views/Shared/_Layout.cshtml
This is default Layout file of Asp.NET Mvc. Empty this and replace these lines.
#{
Layout = ViewBag.Theme;
}
#RenderBody()
You can Modify this way for Areas. You can fetch active template info in BaseController from database or wherever you want.
Btw, if you want to put your views outside of ~/Views folder search for ThemeableRazorViewEngine
in Views/_ViewStart.cshtml
#{
object multiTenant;
if (!Request.GetOwinContext().Environment.TryGetValue("MultiTenant", out multiTenant))
{
throw new ApplicationException("Could not find tenant");
}
Layout = "~/Views/"+ ((Tenant)multiTenant).Name + "/Shared/_Layout.cshtml";
}