ASP.NET MVC view cannot find asset - c#

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.

Related

ASP.NET MVC Razor cannot find views in area

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

ASP MVC Route Default Configuration

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

Add a view and display it?

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

Where do I place my C# code in MVC4?

I only ever had experience in using webforms but I have started learning MVC4 recently to broaden my knowledge. However as someone with only experience in webforms, It took me awhile go get a grip on MVC4.
I've basically set up the displays for the site with the layouts and views and calling the views with the controller.
However I want to move on and start giving the site a purpose, like registration etc. which requires some heavy c# coding.
However I am lost on where I should place my handlers etc. I figured I should do my data connection and all behind-page processes in the controller?
Please correct me if I am wrong.
Generally, you can put your c# code wherever you want. The only conventions that MVC adheres to by default are the Controllers and Views folder. And technically the only reason for the Controllers folder is because controllers placed in there will default to the MyApp.Controllers namespace. Controllers are resolved by name and namespace, not file location (unlike Views).
What I usually do is put business specific services in a Services folder, and utility/infrastructure in an Infrastructure folder.
However, you're free to arrange your c# code however you like.
MVC (Model View Controller).
Your all data access logic code in "Model".
Your view and UI in "View".
Your all business logic code in "Controller".
In order for them to interact with each other. here is a simple example:
Your Model code:
public static List<string> GetCountryData()
{
List<string> lstCountries = new List<string>();
var countryData = yourDBContext.Database.SqlQuery<string>("SPROC_GetCountryData");
if(countryData.Any())
{
lstCountries = countryData.ToList<string>();
}
return lstCountries;
}
Your Controller code:
public ActionResult CountryView()
{
List<string> lstCountries = YourModel.GetCountryData();
return View(lstCountries);
}
Your View:
#model List<string>
<ul>
#foreach (var country in #Model)
{
<li>country</li>
}
</ul>
Hope it will help some.

ASP.NET MVC Routing for Master / Detail Views with "Detail Children"

I have the basic Master / Detail Views working great with the default ASP.NET MVC Route; however I would like to build some URLs like this:
/Class/Details/5 -- General Detail view [Working]
What I'm not sure about (and I'm not tied to this URL format, just something roughly equalivent.)
/Class/5/Details/Logs -- Detail View with Logs
/Class/5/Details/Status -- Detail View with current Status
Another way to put this, is like this:
/{controller}/{id}/{controllerSpecificMaster}/{action}/
What I'm trying to avoid, is cluttering up my Views\Class directory with a bunch of Views, which are all basically derivatives of the Details view.
I'm on ASP.NET MVC 1 and .NET 3.5 SP1.
The first thing you need to get down are your routes. You may have already done this, but in case you haven't, here's a route entry that will handle your custom route needs:
routes.MapRoute("Master_Detail",
"{controller}/{id}/{controllerSpecificMaster}/{action}",
new { controller = "Class",
action = "Index",
id = UrlParameter.Optional,
controllerSpecificMaster = "Details"
});
Then, in your action methods where you want to use the route-specified master page, just include the route key in your method arguments, and then pass it to the view:
public ActionResult Logs(int id, string controllerSpecificMaster)
{
//do something
//return view with master name as argument
return View("Logs", controllerSpecificMaster);
}
If you have to do this a lot, I would suggest creating a custom view engine and override the FindView() method.

Categories

Resources