I've been learning MVC3 a bit for a while and although I understand most of the basics, the routing is something I just can't seem to get a hang off. I'm not sure whether I'm doing/thinking it in a correct way and the other answers I've read on stackoverflow/google only seem to confuse me more.
Anyway here's the situation. I've got a solution (cleaned it up for this question), where I'd like to create a structure in my views folder to organize everything in a structure I've been using for my asp.net webforms projects.
Anyway, I was wondering whether it would be possible to get this kind of structure, where I could organize all my partial views into a specific subfolder called UserControls in which there are more subfolders where I would group every partial view I'd need for a specific page.
Ideally, my Views folder would contain 2 folders: Pages and UserControls and everything I'd need would go into a subfolder, or a sub sub folder.
Okay so if this is possible, how would I start routing this? I've been trying multiple ways of getting any result but they all end up in a 404 errors.
If this is a wrong approach of me, what would be a better alternative?
Thanks in advance!
Logically, this is better served by grouping your partials in with the actual views like so:
/Other
/Partials
OtherPartial1.cshtml
OtherPartial2.cshtml
Index.cshtml
/Some
/Partials
SomePartial.cshtml
Index.cshtml
SomeOtherView.cshtml
Now, you can certainly do as you suggest, but it simply means that your helpers in other views have more text to write to get where they want to go:
IE.
#RenderPartial("Partials/OtherPartial.cshtml")
VS
#RenderPartial("~/Views/PartialControls/Other/OtherPartial.cshtml")
You could manually return the view file for each actionresult or partialactionresult.
I'd also recommend changing "UserControls (PartialViews)" folder to just PartialViews.
e.g.
public PartialViewResult OtherPartialView1()
{
return PartialView("../PartialViews/OtherViews/OtherPartialView.cshtml");
}
Related
I am using ASP.NET MVC5 and I would like to render a view from a folder that is outside the application folder. I tried registering my own custom the VirtualPathProvider and I even created my own VirtualPathProviderViewEngine to support rendering pure html pages. I have the latter working but cannot get the former to work. When I navigate to the route in question, I want MVC to check the internal Views folder for the View and then if it is not found I want it to look in the external folder.
When I step through the code, FileExists gets called for files that are in the Views folder and then the ViewEngine code runs but for a View that lives externally, the FileExists check runs and then I get a 404 on the screen. It does not ever get into the ViewEngine code. I know I am missing something simple here.
I am attaching a screenshot of what the sample folder structure would be. Any help would be greatly appreciated.
You can override the VirtualPathProvider and the VirtualFile
Check this link for an Example
I have just inherited a Xamarin project that keeps the Views (.xib) in a separate folder from the controllers. I find it a little difficult to scroll through the left menu and try to match up the nib files to their controller. So I put the nib files right next to the controller cs file and in the same folder that's organized by domain.
My question is, is there a good reason why they were separated out in the first place? I know a typical MVC application will do this but this is a bit different because a nib file needs to declare the controller.
No good reason that I can think of. It shouldn't matter either way. It's mainly organizational preference. I typically like to keep them together as well.
I'm enjoying using the well-made MVCSiteMapProvider through Nuget at the moment but I've hit a roadblock.
I'm trying to modify the template for the #Html.MvcSiteMap().Menu() helper. The file I'm modifying is ..\Views\Shared\DisplayTemplates\MenuHelperModel.cshtml and no matter what change I make to the file, the template does not update when rendered.
I've done a Find All with notepad++ and found that within MvcSiteMapProvider.dll there is two templates, one for classic asp.net and one for Razor. So clearly the template within the .dll file is being called - but how do I make this not the case?
It may be worth knowing that although the templates are located in ..\Views\Shared\DisplayTemplates\, the site is configured to use a different folder for Views.
edit: also if I pass in a template name to the helper, still no effect.
Templated helpers are an MVC creation, not one of MvcSiteMapProvider. I strongly suspect your issue is due to reconfiguring your Views folder. MVC does not support a way to reconfigure your templates folder.
But as pointed out in the accepted answer, it is possible to put them under ~/Views/CurrentController/DisplayTemplates/. You might be able to use that feature to put the templates in your newly configured folders. This means that you would need to add a copy of the templates for every single controller, though.
The best solution is not to change the MVC folders from their defaults.
If that is not an option, you might consider rolling your own Menu HTML helper based on the code from the current one that returns an HtmlString rather than using templates.
The templated helpers are better because you can edit the code after it is deployed (which is why we did it that way), but it comes with the caveat that you have to rely on MVC's default folder structure to use them.
I have asked this but it was marked as a duplicate, I do now want to add more folders to where the viewengine looks I want to control where it looks by passing more parameters to the RenderPartial.
I have been trying to figure this out and have been struggling, is it possible to control the shared folders, we have a lot of areas in our application and some of the views in those areas are used in multiple places and the Shared folder under views is getting huge so would it be possible to create a way to do the following:
<% Html.RenderPartial("SomeIdentifer", "ViewName"); %>
If we could do that we could have it look at the shared folder under the area "SomeIdentifier" or create a "SomeIdentifier" folder under the root views shared folder.
Is this possible?
For the record I don't want to add lots more folders to be searched as surely that will slow down the finding of a view and also there could be views with the same name. I want to tell the RenderPartial where to look, in this case look in a folder under shared called "SomeIdentifier".
You can specify the full path to your view like:
<% Html.RenderPartial("~/Views/SomeFolder/YetAnotherFolder/yourview.cshtml", "ViewName"); %>
There something I still do not understand about how the Content folder works in ASP.NET MVC. To make things clearer I have a few questions:
Is the Content folder the root folder? I mean does http://localhost/ point to Content or is it something else?
I have a file named dummyIcon.png inside Content/images/temp folder. How do I locate it from my domain layer (which is a Code Library project)?
What is the best practice of displaying images in ASP.NET MVC? Should I store a path to the image in the database (which I personally prefer), or do I save a byte array and return it to the view?
I found the following links to be helpful within the context of the MVC web application, but I'd still appreciate some answers to the questions posted above. Thank you.
Can an ASP.NET MVC controller return an Image?
how to display image using view and controller by ASP.NET MVC
Anything in the root will point to the root if it is ignored by your routes:
If you have an image placed on the on the root of your project. Then, say http:://localhost/dummy.ico" will give you a 404, no controller found. Until you do this in your global.asax.cs:
routes.IgnoreRoute("dummy.ico");
//you could add wildcards here to match different things
From Code if you use says File.Open(); you need the physical path to the file. You get it like this:
string filePath = Server.MapPath(Url.Content("~/Content/Images/Image.jpg"));
It is upto you here, although I would say, putting files into the database makes a lot of sense if you want everything in one place. If you need to move your app around you would just move the data base.
When it comes to file paths, please remember you don't want duplicate file names, so you will have to give each file a GUID and then link it up. It could make sense if you have a large number of files (or large files itself) so you're database won't grow like crazy.
HTH
1.Is the Content folder the root folder?
I mean does http://localhost/ point to
Content or is it something else?
No, http://localhost:port/ does not point to content folder. You can access files in content folder through http://localhost:port/content/...
2.I have a file named dummyIcon.png
inside Content/images/temp folder. How
do I locate it from my domain layer
(which is a Code Library project)?
You should be able to access it as http://localhost:port/Content/images/temp/dummyIcon.png
3.What is the best practice of
displaying images in ASP.NET MVC?
Should I store a path to the image in
the database (which I personally
prefer), or do I save a byte array and
return it to the view?
Where you store the images depends on your application needs. Are these generic images that is used to display application images (icons, company logo, etc).. Then it is best to store them in file system.
If your application deals with images and you work on storing images, manipulation etc, then you may need DB. I think, storing images used on the web application is a overhead.
You should make a model object for your controller to return. in this example i am returning SearchPageModel, a class i have created. but lets say this object has a property called imageURL
but make sure the controller actually returns an ActionResult
so for example...
[AcceptVerbs(HttpVerbs.Get)]
public ActionResult Search()
{
SearchPageModel Model = new SearchPageModel();
// populate the Model properties
Model.ImageURL = "myjpeg"
return View("Search", Model);
}
i then pass this model object back to my desired view in this case my "Search" View
and to display the image, in the view i would add..
<img src="Images/<%=Model.ImageURL %>.jpg" />