URLs work correctly
Actions work correctly
the only problem is that the razor engine is just searching for view files in ~/Views and not in ~/Areas/Admin and I don't know why is that because it used to work fine
It works when I fill the return view type of the action by the exact path of its view but the absolute path for views is not working
Here is one action for example but none of the actions in the admin area can call their views
Even _Logout which is a partial view ib Shared cannot be called by _Layout unless using the full path
Action in Controller:
// GET: Admin/Login
[Route("Admin/Login")]
public ActionResult Login()
{
return View();
}
Error:
The view 'Login' or its master was not found or no view engine supports the searched locations. The following locations were searched:
~/Views/Default/Login.aspx
~/Views/Default/Login.ascx
~/Views/Shared/Login.aspx
~/Views/Shared/Login.ascx
~/Views/Default/Login.cshtml
~/Views/Default/Login.vbhtml
~/Views/Shared/Login.cshtml
~/Views/Shared/Login.vbhtml
Solved!
[RouteArea("Admin", AreaPrefix = "")]
Was missing from top of my controller
Related
I want to edit blogs. I have Edit view in View folder in BlogAdmin folder.
Edit
Controller:
public ActionResult Edit(int? id)
{
if (id == null)
{
return HttpNotFound();
}
List<Blog> EditBg = db.Blogs.Where(i => i.id==id).ToList();
if (EditBg== null)
{
return HttpNotFound();
}
var vm = new VmBlog
{
blogcatg = db.BlogCategories.ToList(),
Blog = db.Blogs.Where(i => i.id == id).ToList(),
Content=db.Blogs.FirstOrDefault(i=>i.id==id).posttext
};
return View(vm);
}
Get method is working. There is no error here:
Everything seems correctly. But I am getting this error:
The view 'Edit' or its master was not found or no view engine supports the searched locations. The following locations were searched:
~/Views/BlogAdmin/Edit.aspx
~/Views/BlogAdmin/Edit.ascx
~/Views/Shared/Edit.aspx
~/Views/Shared/Edit.ascx
~/Views/BlogAdmin/Edit.cshtml
~/Views/BlogAdmin/Edit.vbhtml
~/Views/Shared/Edit.cshtml
~/Views/Shared/Edit.vbhtml
Why does error happen?
Check Microsoft documentation on Views, specifically the section about View Discovery
It doesn't matter if you implicitly return the ViewResult with return View(); or explicitly pass the view name to the View method with return View("");. In both cases, view discovery searches for a matching view file in this order:
Views/[ControllerName]/[ViewName].cshtml
Views/Shared/[ViewName].cshtml
It seems that your folder structure does not account for the specified view discovery
If you want to change the folder structure and View discovery
You can customize the default convention for how views are located within the app by using a custom IViewLocationExpander.
A very nice answer on this, can be found Working with IViewLocationExpander in mvc
#Aytac,
In the MVC pattern the default routing puts controllers into a folder at "/controllers". Views are stored in a folder at "/Views/{ControllerBaseName}/{ActionName}".
The default folder structure (routing) should look like the following (tagged as c# so assuming c# extensions):
/Controllers/BlogAdminController.cs
/Views/BlogAdmin/Edit.cshtml
I'm making an ASP.NET MVC website. Most of my views are under the View and their respective subfolders, and they are called Index. These views have no trouble fetching CSS and Images. These classes have localhost:51227/example like URLs.
However, when I add a view that is just another ActionResponse of a controller, the view cannot find any of my assets (images, css etc.). These views have localhost:51227/example/action.
What am I doing wrong with my routing?
Sample code:
public ActionResult Day()
{
ClientViewModel cvm = new ClientViewModel();
cvm.Page = Page.TIMESHEET;
return View(cvm);
}
This is my Controller ActionResult.
The thing was that my inner URL's didn't start with a / so I wasn't looking from root.
Stupid question, sorry.
I'm new to ASP MVC programming and wanna ask about how the route is configured.
For example I have the Home Controller
public ActionResult Home(){
return View("Index")
}
This will find the Index.cshtml under /Views/Home/
However if I rename the Home Folder to Homees for example, the view is not found and also I try to return View with View("~/Views/Homees/Index.cshtml") this is not change that the controller not found the view.
Is this the default of the asp mvc? and it's possible to change this one?
There are few points.
ASP.net MVC is convention based. It is also specified by #Petar Minev. When it comes to search for view it use following method. It take controller name as directory name and view name file name with different extention ( like cshtml, vbhtml , aspx ) based on view engine. ( As you are using cshtml it seems that you are using both Razor and Webform view engine).
For search it will first go to directory with controller name and search for specified view. If it is not available there then it goes to shared folder.
Above is default behavior of ASP.net MVC.
Now you change folder name then first solution you have tried that must work as it works for me. ( Please check that your folder name is correct. Make sure you did not rename for area directory).
public ActionResult Home(){
return View("~/Views/Homees/Index.cshtml")
}
Another solution is to rename controller with HomeesController ( So it will automatically locate correct directory)
If you continue with this convention for other folder like the way you add "es" in "Home" it is better to add this convention in default search for view.
( You can do this by either inherit from default RazorViewEngine or change RazorViewEngine parameter)
For example
protected void Application_Start()
{
RazorViewEngine engine = (RazorViewEngine)ViewEngines.Engines[1];
List<string> currentFormats = engine.ViewLocationFormats.ToList();
currentFormats.Insert(0,"~/Views/{1}es/{0}.cshtml");
engine.ViewLocationFormats = currentFormats.ToArray();
... Other application start code
}
Razor View engine is default view engine for ASP.Net MVC. This Razor view engine is configured to locate path at specified path i.e. "~/Views/{1}/{0}.cshtml".
Here {1} placeholder specifies controller name and {0} represents view name.
Say, for Example any request for Index action in Home controller will look for view at "~/Views/Home/Index.cshtml".
Now if you want to change this default path then you have to define custom view engine. Here a sample example how can you define a custom view engine and change the default path.
public class MyCustomViewEngine : RazorViewEngine
{
public MyCustomViewEngine()
{
ViewLocationFormats = new string[] {
"~/MyViews/{1}/{0}.cshtml",
"~/MyViews/Shared/{0}.cshtml" };
MasterLocationFormats = new string[] {
"~/MyViews/{1}/{0}.cshtml",
"~/MyViews/Shared/{0}.cshtml"};
PartialViewLocationFormats = new string[] {
"~/MyViews/{1}/{0}.cshtml",
"~/MyViews/Shared/{0}.cshtml"};
FileExtensions = new string[] { "cshtml" };
}
}
You also need to register custom view engine with ASP.Net run time at Application _Start() event.
ViewEngines.Engines.Clear();
ViewEngines.Engines.Add(new MyCustomViewEngine());
Your controller code is seems wrong, if your controller name is Home then code will be like this with index action
public class HomeController : Controller
{
public ActionResult Index()
{
return View("~/Views/Homees/index.cshtml");
}
public ActionResult Contact()
{
return View();
}
}
you just used the controller name as action name, by default in view folder there is a separate folder for each controller like for Home controller there will be a folder named Home, and inside that there will be separate cshtml file for each action result, like for my code there is a two action result name Index and Contact so under Home folder there will be two separate cshtml for both as index.cshtml and contact.cshtml. So when we request index action it will go for index.cshtml and for Contact action contact.cshtml by default, but we can spacify our own view for any action like my index view, and it works fine, your approach was correct but only problem was the Controller name and action name I think, try this way it may help
by default Microsoft's ASP.NET MVC is created over one Folder Convention which means that all files that will be Controllers should be under Controller folder, each file which will be View should be under View folder,
also if you create Mvc Route for example MyProfile, in the MVC you'll get contorller with this name and folder under the view's.
All this is controlled by the default routing which is knowing where to find, Views and controllers, so if you want to make some changes or modifications you should go to ASP.NET web site and look some tutorials for MVC Routing
Hope i helped :)
Simple just go to App_Start and Open RouteConfig.cs File and change route controller "Home" to "Homees" by default it set as "Home". If you rename your HomeController to "HomeesController" you should change to rountconfig by default route. check below image
After that open "HomeesController" from Controller folder here you can add action for view
public ActionResult Index()
{
return View();
}
and Add Action to View "Homees" Folder
I'm totally new to MVC. Now I'm trying to create a View in the folder Sample( which is under the folder of Views). I right-clicked the Sample folder and selected "Add View", then hit the view name as Test. After the view has been created, I typed in following code:
<!DOCTYPE html>
<html>
<head>
<title>Sample View</title>
</head>
<body>
<p>
Test
</p>
</body>
</html>
Build. Then I tried to navigated the address http://localhost:24694/Sample/Test in my browser. But the browser read "The resource cannot be found.". Why? I've also other cshtml files in the Sample folder(which was generated by others), they worked fine. For example, there is a file called "Message.cshtml" under the folder of Sample, and I can navigate the address http://localhost:24694/Sample/Message with ease. Is there anything that I should add?
3 Step Process
1 - Define the Route
routes.MapRoute("Test", "test",
new { controller = "NameOfController", <- In your case TestController
action = "Index", <- Name of action in controller returning view
parameter = "parameterName - leave empty if no params needed"
});
2 - Create the controller
So if you follow the above method and call your route Test and the view Test then you need to create the controller called TestController. MVC automagically sows these together thanks to your route config you did earlier (RouteConfig.cs)
3 - View
In your case you just make sure the view is returning something.
Easy as that. Good luck.
you cannot use
http://localhost:24694/Sample/Test
to navigate to view because you can only access a view through a controller. so follow these steps
First of all create a new controller inside controllers folder and name it 'SamplController'.
By default there will be an action method named Index().
Create a new Action method named 'Test' inside 'SampleController'
Now right click inside 'Test' action method and click on Add View. it will add a new view insides Views folder named 'Test.cshtml'. You can use it. if you want to place this View inside other folder then you've to modify the return statement of 'Test' action method. For example you created a folder 'MyViews' inside Views folder and moved 'Test.cshtml' there. Now your return statement in 'Test' action method will be like this
return View("~Views/Sample/MyViews/Test.cshtml");
instead of
return View();
Now when you use
http://localhost:port/Sample/Test
it will create a new instance of 'Sample' Controller and will call 'Test' action method. This method will return specified view. i hope it will help :)
ASP.NET MVC is based on routing not in file system like asp.net webforms. Following the internals, views should be in the Views folder from the ASP.NET MVC application template, like Controllers should stay on the Controllers folder. It is not required, but it is setted by default from asp.net mvc framework.
In your a Controller (class), you could have some Actions (methods), which can return a view, image, file, etc, implementations that derive from ActionResult type. Theses actions, could return a view using the View method from the controller base class. By default, the asp.net mvc will search for a view (.cshtml or .aspx file) inside the ´Views` folder and in a folder with the same name of the Controller, for sample, if you have a controller like this:
public class ProductController : Controller
{
public ActionResult Index()
{
return View();
}
}
It will find a view in Views/Product/Index.cshtml and render it for you. I recommend you reading more in http://asp.net/mvc
When I'm inside Admin area and map my routes using attribute routing it cannot find view because it doesn't look inside actual area view folders but instead only global view folders.
Only if I pass full path to view it then can display it, otherwise it throws me error.
Error
The view 'Authorize' or its master was not found or no view engine supports the searched locations. The following locations were searched:
~/Views/Home/Authorize.aspx
~/Views/Home/Authorize.ascx
~/Views/Shared/Authorize.aspx
~/Views/Shared/Authorize.ascx
~/Views/Home/Authorize.cshtml
~/Views/Home/Authorize.vbhtml
~/Views/Shared/Authorize.cshtml
~/Views/Shared/Authorize.vbhtml
Code
[RoutePrefix("admin")]
public class HomeController : Controller
{
[Route]
public ActionResult Index()
{
return View("Authorize"); // Error
return View("~/Areas/Admin/Views/Home/Authorize.cshtml"); // Working
}
}
Note that if I disable attribute routing and switch back to good old routes it will work. Any way of fixing this or it's working as intended and I should apply full path in all my areas?
You need to add the [RouteArea("")] attribute to your controller:
[RouteArea("Admin")]
public class HomeController : Controller
You can find the documentation here.