I'm learning Asp MVC.
I've been doing WPF MVVM programs for two years already, but i also need to learn ASP which is a common language used in web development in my country as far as i know. And i have also knowledge in c# so i think adjusting will not be very hard, but i'm already facing a lot of problems in making my website work. I tried reading about ASP and MVC but i learn by doing things and from my mistake than reading it. So i decided to give it a try.
I created an EMPTY MVC project using Visual Studio Community Edition 2017
I already created the Layout Page and the First Controller and the First View and its totally working fine.
This is the screenshot
Then i create the second controller. Then the problem comes in.
I created a new controller named NewPostController and ADD View for it like this
But it create another folder with the name of the View and inside it is the view it created
I don't want it to organize that way.
So i dragged the NewPost.cshtml into the admin folder. Run the application then i received an error saying
The resource cannot be found.
Requested URL: /Admin/NewPost
I did a search for a solution but i can't solve the problem
I tried specifying the view name
public ActionResult NewPost()
{
return View("~/Admin/NewPost");
}
Most of the solution i read is specify the View Name. But i can't make it work. What are the things that i missed? Or not understand? Thank you.
MVC have sort of a naming convention where if your controller is named FooController then your views should be keep in a folder name Foo.
Inside this controller you will have your
public ActionResult <name of view>
name exactly the same as the view for easy referencing.
So when you have a view under the Foo Folder and the name of that cshtml file is Hello
then inside the FooController, you have a
public ActionResult Hello(//parameter here){
//body here
}
Hope you understand my explanation.
Also to answer your question. I'm assuming you want the NewPost.cshtml as part of the admin folder. Just add
public ActionResult NewPost()
to your admin controller and then you can use
localhost/admin/NewPost()
If i miss anything or any error, please comment hehe answered this in a bit of a rush
Just move your NewPost action to your AdminController as such:
public class AdminController : Controller
{
public ActionResult Dashboard()
{
return View();
}
// Here you go
public ActionResult NewPost()
{
return View();
}
}
This is default MVC structure if you want both Dashboard and NewPost views to be in the Admin folder
Related
I don't have much experience working with resource files, but the little that I have is from Web Forms. There from what I can tell is you create a resource file called let's say InternalMessages.resx and then you create a Spanish version Errors.es.resx. Now if I have set up my code correctly for choosing language, all I have to do it call InternalMessages.MyMessage and it will choose the right language, regardless of what page you are on.
In core, this concept doesn't seem to work. no matter which language I switch to, it just uses the English translations. From reading the documentation, it appears that core wants me to create resource files on the page level, however, I find this very bad practice because it doesn't follow the DRY principle. Sometimes we have values that are used on more than one page and if we decide to change verbiage of that value, we have to go and find it everywhere in the system, other times you may miss that you already have a translation for that or something very similar that would do and you end up paying for translation all over again.
I want to segregate my resources into categories and use them like that. So having the InternalMessages.resx file is how I want to go, however, that doesn't seem to work for me. Here is a SO answer I followed to setup my localization. Localization in Asp.Net Core
So I have a working drop-down with languages, but the code just always pulls the values from InternalMessages.resx versus InternalMessages.es.resx when I switch to Spanish. Why is that?
public class HomeController : Controller
{
public IActionResult Index()
{
ViewBag.Test = InternalMessages.Test;
return View();
}
}
In the view I have:
<p>#ViewBag.Test</p>
I have also tried doing this:
public class HomeController : Controller
{
private readonly IStringLocalizer<InternalMessages> _localizer;
public HomeController(IStringLocalizer<InternalMessages> localizer)
{
_localizer = localizer;
}
public IActionResult Index()
{
ViewBag.Test = _localizer["Test"];
return View();
}
}
But in this case the value I always get is Test
I also tried injecting directly in the View but the result is same as above, just a word Test
#inject IHtmlLocalizer<InternalMessages> SharedLocalizer
<p>#SharedLocalizer["Test"]</p>
This question already has answers here:
How to serve html file from another directory as ActionResult
(6 answers)
Closed 5 years ago.
We have a .NET 4.0, MVC 2 project, where the HomeController looks like this:
[HandleError]
public class HomeController : Controller
{
public ActionResult Index()
{
return View("~/client/index.html");
}
}
All is fine.
But, when we start linking to .NET 4.5 and MVC 4, the runtime can't seem to find this index.html! We get this error:
The view '~/client/index.html' or its master was not found or no view
engine supports the searched locations. The following locations were
searched: ~/client/index.html
How could this be! What might we be missing here.
I've never seen MVC using straight html pages. This is a more typical setup:
Controller
[HandleError]
public class HomeController : Controller
{
public ActionResult Index()
{
return View("Index");
}
}
The view would be /views/Home/Index.cshtml. By default MVC wants views to be in the views folder in a folder corresponding to the controller name.
If you want to have the layout broken into a separate file it would typically be in /views/Shared/.
If your HTML page is self-contained you should be able to move it and rename it to index.cshtml and add the following somewhere on the page.
#{
Layout = null;
}
Take care when locating your html page. Placing it inside a view folder where, by the MVC rules, a controller would be expected to do the handling, causes errors in my testing. Here's one way to make it work, though this isn't really coding to MVC pattern:
You can then reference the page:
Notice I've stepped outside the controller/view structure (not recommended for MVC)
To make it fail, which I'm assuming is similar to what is happening for you:
(notice the html is placed in a view where we'd expect a matching controller method to serve it to a caller)...
But...
So if you insist on going this approach perhaps you can set up a content folder outside your MVC controller/view structure and place your html there. But, again, not to beat the subject to death, you could easily convert this to cshtml and serve it up via a simple method in a controller. Just my two cents' worth..
I have been asked to work on already existing code for a .NET MVC Application, and am required to add a new page. I have done this, but am having issues.
The application has a common layout defined in _Layout.cshtml page (I need to use the same layout for my new page). The path is present in Viewstart.cshtml page.
This is how an existing page works:
The controller has this code:
public ViewResult Index()
{
TransactionHistoryViewModel model = new TransactionHistoryViewModel();
model.SearchType = "TransactionHistory";
return View(model);
}
When the code is run, immediately after executing the above lines, it goes on to the _ViewStart.cstml file and executes the following:
#{
Layout = "~/Views/Shared/_Layout.cshtml";
}
But when I try to use the same logic for the controller I have created (I have already set up the models):
public ViewResult Index()
{
TransportPlannerViewModel model = new TransportPlannerViewModel();
model.SearchType = "TransportPlanner";
return View(model);
}
the code stops executing after the above block, and does not move on to the _ViewStart file (I figured this out using breakpoints).
I am required by my employers to maintain consistency with the existing code, so I have tried to stick to the original coding style. Could this be an issue with wrong model mapping or setup?
If you have 2x public ViewResult Index() in the same controller, it is not going to work, you will confuse the application about which method signature to choose, because they are identical.
You should have your TransportPlannerViewModel code in a seperate controller. and this should be pointing to a different View Folder associated with that controller.
Ie. If the controller for the first code block is TransactionHistory, then it will be looking for a view under Views\TransactionHistory\Index.cshtml.
By default it uses the pattern Views\ControllerName\ActionName (methodName) to look for the view.
So to get it to work for your other method, if I understand what you are trying to do correctly, you should have a TransportPlanner Controller, then it will look for your view under Views\TransportPlanner\Index.cshtml.
Please clarify if this is not what you are wanting to do.
I'm new on asp.net mvc. I created a basic controller and I tried to open it using url. But rendering is not finished and my controller didn't display in several minutes. I did not change anything from default asp.net 5 mvc project also my controller's index method return only hello world string. I don't is there any problem on iis or VS. Any idea about that problem?
Thanks for help.
In MVC only public methods that return an ActionResult are accessible as web pages.
So you MUST use something like this:
public class HelloWorldController : Controller
{
// GET: HelloWorld/Index
public ActionResult Index()
{
return Content("This is <b>Index</b> action...");
}
// etc
}
Content(...) is a special method the wraps text into an ActionResult.
Note: only use Content(...) if you specifically do NOT want to use a View such as Index.cshtml - which is what you normally WOULD do, of course.
I have opened a sample ASP.NET MVC project.
In HomeController I have created a method (action) named MethodA
public ActionResult MethodA()
{
return View();
}
I have right clicked on MethodA and created a new view called MethodA1
Re-did it and created a new view called MethodA2.
How is this magical relationship done? I looked for the config to tell the compiler that views MethodAX are related to action MethodA, but found none.
What view will the controller return when MethodA is called?
The convention is that if you don't specify a view name, the corresponding view will be the name of the action. So:
public ActionResult MethodA()
{
return View();
}
will render ~/Views/ControllerName/MethodA.cshtml.
But you could also specify a view name:
public ActionResult MethodA()
{
return View("FooBar");
}
and now the ~/Views/ControllerName/FooBar.cshtml view will be rendered.
Or you could even specify a fully qualified view name which is not inside the views folder of the current controller:
public ActionResult MethodA()
{
return View("~/Views/Foo/Baz.cshtml");
}
Now obviously all this assumes Razor as view engine. If you are using WebForms, replace .cshtml with .aspx or .ascx (if you are working with partials).
For example if there is no view it will even tell you where and in what order is looking for views:
Remember: ASP.NET MVC is all about convention over configuration.
The MVC framework use convention over configuration. The framework calls the ExecuteResult on the ViewResult object (created by the return View();). The framework by convention then looks in a number of locations to find a view
If you are using areas the framework will look in the following locations for a view.
/Areas//Views/ControllerName/ViewName.aspx
/Areas//Views/ControllerName/ViewName.ascx
/Areas//Views/Shared/ViewName.aspx
/Areas//Views/Shared/ViewName.ascx
/Areas//Views/ControllerName/ViewName.cshtml
/Areas//Views/ControllerName/ViewName.vbhtml
/Areas//Views/Shared/ViewName.cshtml
/Areas//Views/Shared/ViewName.vbhtml
Without areas (or if you are using areas and no view has been found) the framework will look at the following locations
/Views/ControllerName/ViewName.aspx
/Views/ControllerName/ViewName.ascx
/Views/Shared/ViewName.aspx
/Views/Shared/ViewName.ascx
/Views/ControllerName/ViewName.cshtml
/Views/ControllerName/ViewName.vbhtml
/Views/Shared/ViewName.cshtml
/Views/Shared/ViewName.vbhtml
As soon as the Framework tests a location and finds a file, then the search stops,
and the view that has been found is used to render the response to the client.
There are a number of overriden versions of the View method. The most common one is to render a specific view, outside of the framework convention, by calling it by name. For example
return View("~/Views/AnotherIndex.cshtml");
As an interesting footnote, the framework looks for legacy ASP, C# and VB Razor views (aspx, ascx, cshtml and vbhtml) even though you have a specific view engine.
In MVC controller action is not bound to view.
It uses delegate mechanism to pickup the view.
Model Binding(Mapping)
I was looking for the same and I just made a couple of tests and figured out.
It doesn't save anywhere.
To understand how it works; just do these steps:
In your controller, right click, Add View
Then enter a different View Name
and Ctrl F5
you will get Server error in application.
For example if you right click , Add View in following Index action method and type "Index2" in View name, you will get the error.
public class TestController : Controller
{
// GET: Test
public ActionResult Index()
{
return View();
}
}
So basically there is a 1-1 matching between action name and View name. And you cannot add view for the same method so there is no need to save in a config file.
Now change the view file name in Visual Studio from Index2.cshtml to Index.cshtml then Ctrl+F5. You should see it is working.