I created a Asp.net mvc project on visual studios, In the many folder I get I have a folder called Home that has three .csthml files: about.cshtml, contact.cshtml, and index.cshtml.
I would like to change about.cshtml to blah.cshtml and contact.chstml to lala.cshtml.
I've tried to do it from properties but the name is not changed across other files in the project.
Should I use those files in my project or create another controller?
click on the file, push F2 and then rename (type in the new name) or right click the file and select rename. Make sure that you are not running the application (which may be the issue).
If you do change the name, the action in the controllers should also probably be updated.
Also, you can rename only view and then set [ViewName()] attribute for the action.
For instance, you renamed about.cshtml to blah.cshtml:
[ViewName("~/Views/Home/blah.cshtml")]
public ViewResult About()
{
...
return View();
}
However, better keep names the same
Related
I have the following:
Html.RenderPartial("~/bin/Views/SharedViews/_PartialView.cshtml", model.SharedViewModel);
This partial view is coming from another project that I have set as a reference; that partial view is set to Copy to Output Directory because MVC doesn't allow you to reference partial views outside of your web project. I am leveraging a reusable MVC component so I am copying this view from one project to the bin directory of the primary project:
Project.Common
> Helpers
>> _PartialView.cshtml (Copy to Output Directory = true)
Project.FirstProject
> References
>> Project.Common
> bin
>> (copied) _PartialView.cshtml
I see the file in the bin folder; the MVC rendering engine is locating it as well, too. I've validated this by changing the path and observing an error related to the view not being found. So - MVC finds the view, but throws this error:
_PartialView.cshtml(1): error CS0103: The name 'model' does not exist in the current context'
Contents of _PartialView.cshtml:
#model Common.ViewModel
#if (Model.Check)
{
<p>success!</p>
}
If I modify the contents to be just HTML:
<p>test</p>
I get the same error. If I then modify the invocation to use Html.Partial instead of RenderPartial, I get the same error.
What's going on here?
If I then remove the viewmodel from the invocation, I get:
The view at '~/bin/Views/_PartialView.cshtml' must derive from
WebViewPage, or WebViewPage.'
With both RenderPartial and Partial.
Adding #inherits System.Web.Mvc.WebViewPage to the top of the partial view gets the html rendering, but doesn't fix the cshtml The name model does not exist error.
Updating the View Engine to include the bin folder and referencing the view without the full path specified isn't working - the view engine cannot locate the view even after implementing the following:
public class CommonAccessibleViewEngine : RazorViewEngine
{
public CommonAccessibleViewEngine()
{
// added to leverage reusable pagination component (and other reusable view components)
// MVC by default doesn't allow you to reference Views outside of your immediate project. By setting views to copy to output directory and then modifying the engine as follows,
// we're telling the view engine to expand its scope to include these referenced views in addition to its default scope.
var newFormats = new string[2] { "~/bin/Views/YourFolder/{0}.cshtml", "~/Views/Shared/{0}.cshtml" };
this.PartialViewLocationFormats = newFormats;
this.ViewLocationFormats = newFormats;
}
}
With this in Application_Start:
ViewEngines.Engines.Add(new CommonAccessibleViewEngine());
Linking the view also does not work:
Linked Partial View Not Found By MVC
Workaround:
Ensure the Partial view includes #inherits System.Web.Mvc.WebViewPage - this allows you to reference ViewBag. Model is still not accessible.
Use a custom view engine (as above) to specify the location of the file (bin for me)
Assign whatever Model your Partial view expects as a ViewBag property:
ViewBag.PartialViewModel = partialViewModel;
Cast ViewBag in the Partial View:
#{
var Model = (Common.ViewModel)ViewBag.PartialViewModel;
}
Go balder from the fact that Microsoft makes a core tenant of quality programming - reusability - such a nightmare to figure out within MVC.
I think it's because you are copying a CSHTML to the output directory; if you turn off Copy to Output Directory, the path to your partial view can become:
~/Views/Shared/_PartialView.cshtml
Or whatever the actual path happens to be.
For Html.Partial("View"), the view needs to be in either in the Shared folder, or the executing controller's folder for the view engine to find it. You can simply define the name of the view without the file extension.
EDIT
You can also link the item into the web project at a specified directory using the Add as Link option: https://blogs.msdn.microsoft.com/zainnab/2010/11/12/linked-items-in-projects/
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
For example, I need only documents from a folder on the server drive X:\Docs for an online web application. Is there a way that a button on the website will open X:\Docs by default? I have tried this to open specific folders with no luck:
[HttpPost]
public ActionResult Index(HttpFileCollection file)
{
var path = System.IO.Path.GetDirectoryName("X:\Docs");
return RedirectToAction("Index");
}
I am new to C# and MVC. Is this achievable?
You can enable directory browsing of that folder and then having the button (or href) to point to the url. You don't event need a controller method for it.
Updated: if the folder is not under your website's root you will need to do some work by yourself. For example
#foreach (string path in Directory.GetFiles("X:\Docs"))
{
<div>
<!--doc link-->
</div>
}
You will need to have read permission for that drive ofc
As Luke pointed out you could alo do this inside your controller and pass it into your View which I also think it might be a better approach since View should be responsible for reading and rendering data
I changed the name of view files (Index.cshtml -> Performance.cshtml), and when I execute the project, the application can't recognise the new view name. I changed the name of an action in controller accordingly (ActionResult Index() -> ActionResult Performance()). However, it keeps saying HTTP 404 error.
When you change your view name mvc application can't find a proper view for it's controller action method.
If it is your default page view( load on application start) than you also need to make changes in your Route_config file.
See the image below Change controller = " Name_of_controller" & action="name_of_action" in your case action name will be Performance.
Always Remember in mvc you can run any method using browser url
for example : controller is home & method is Performance than url will be localhost:port/home/Performance
Change the default route defined in App_Start/RouteConfig.cs file to set Performance as the default action.
Or, you can run the project with the following URL:http://localhost:port/home/Performance
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.