my problem is about returning a view from a different controller's views list. (MVC3)
first of all I am using areas, but in this case both controllers and views are in the same area.
in the controller;
in the DocumentController
I am returning a view from BelgeController like
return View("~/Areas/Fin/Views/Belge/Details.cshtml", belgeView);
the problem is in both view folders Document and Belge, there is a partial named edit.cshtml, and when Belge/Details view is rendered, Mvc finds and uses the wrong edit.cshtml, are there any easy ways of referring to the right partial view.
I used this approach all along the project, so there are 100s of Edit.cshtml's, so I am looking for an easy fix.
EDIT:
So, then the question is how can I pass a model to another controller with RedirectToAction.
I'm not sure on the use case, but generally speaking a controller shouldn't be serving anything that another controller is responsible for. it should either return a view of its won which has RenderAction calls to the other controller, or it should do a redirect.
You could just put the partial view in shared and give it a specific name, ie: BelgeDetails.cshtml
and then you should be able to return View("BelgeDetails", belgeView);
If you need to return a view form another controller, you should be using RedirectToAction. If you need a partial view, each controller should have its own sets of partial views that it uses for its own purposes. Controllers are meant to be self-service and self-reliant. Your pattern should not require different features from different controllers.
That said, it is perfectly reasonable to use jquery ajax calls to OTHER controllers to manage dynamic elements of your page (such as pop up modals and the like). This will allow you to create dynamic page elements without dumping all your code in one controller.
There is are two more options:
1) moving the data around in a tier in the model, so that the model of the BelgeController has the information needed, and call RedirectToAction.
2) hack it with ViewData passed to RedirectToAction.
Related
I'm very new to sitecore and just started learning sitecore over at a dev-course held here in town.
The course is WebForms-focused, and since that's not my "patter of choice" I thought I would see how far I can get using MVC in Sitecore.
However, I have a slight problem. I have noticed how there are Controller Renderers, but and how they are bound to a Controller and such. but how about using a Controller for a Layout?
Lets say I have a layout, that for instance might statically render a menu on the top of the site. Then in this case I would like to avoid having a huge amount of code in my view for rendering the menu-items. Instead I would like to have build and populate a custom view model with the menu items and then simply pass down the model to the view and iterate through my menu items within my model.
But I just cant find a way of how to create a controller for a Layout. Any ideas?
Actually, this is possible, you can create a model deriving out of RenderingModel class or implement IRenderingModel interface and assign it to any MVC rendering or layout in Sitecore. Model object will be instantiated by the Sitecore's GetModel pipeline defined in Sitecore.Mvc.Config file.
See Here
Another way to handle this scenario is to create a Menu view rendering and then insert into a placeholder defined within the layout possibly a header placeholder. This can be statically assigned via standard values.
Kevin is right, thats not possible. Actually, Sitecore uses the layout to recognize a view extension and handle the request with MVC (TransferMvcLayout processor in the httpRequestBegin pipeline).
You should consider an approach where you add a placeholder in your layout:
#Html.Sitecore().Placeholder("menu-placeholder")
Then add a Menu Controller Rendering to that placeholder. That way you can utilize the rendering cache as well.
I don't think this is possible. But you can create a Razor view as layout, which works same as a View Rendering. Just just need to specify the path to the Razor view in the Path field and insert a model. In the model you could have simple property, which loads your menu items from whereever you want:
public class MyViewModel
{
public IEnumerable<MenuItem> MenuItems
{
return MyMenuUtil.LoadMenuItems();
}
}
This avoids lot of code in the Razor view and also in the model.
I'm have written a Custom Html Helper and and it can be called from any view like the following #Html.FootNoteNumberedLink. The problem is that I have a fairly complex set of partial views nested within the view and this particular helper needs to keep track of the data that has been added via other partial views. In other words, it is keeping a running tally of all the Footnotes for the entire view (that contains partial views). The problem is that #Html seems to be instantiated at every partial view load. Meaning that my helper can not have a footnotes 1,2,3 from partial view 1 and continue on with the footnote 4, 5, 6 on partial view 2, instead the HtmlHelper is new on every partial view hence the data can not be appended.
The internal workings of the footnote are using ViewData to store the list of foot notes as such: ViewData[ViewDataKey] as List
Any anyone explain why MVC is doing this or am I doing something wrong?
As usual thanks for your help.
The HtmlHelper is intented to be used as a simple markup generator class. Using it for keeping track of changes is probably not a good idea.
Instead, I would create a strongly typed viewmodel and populate it in the controller.
Then you can pass the viewmodel to your main view and just print it.
Your views should do nothing except painting whatever information the controller is passing.
I have a question for the pros and cons on how reusable partial views should be used in a project.
In the first example, I have a layout that is used between all the views. In the layout, I have a partial view that gets called using Html.RenderAction("Index", "Header"). This header changes based on if the user is logged in or not and it renders on every view.
In the second example, I have a static layout that is used between all the views. However, in this layout there are no partial views being called. The Header partial view is being called on each view and basically does the same thing as the first example (changes based on if a user is logged in or not, etc.)
Which approach is better, is one way or another the correct way? Pros and cons of each?
One of the main ideas behind asp.net-mvc is to not reuse code. So with this in mind, you should have your Header code in your _Layout file. This way it is not being retyped in every View, and if you needed to remove it or add route values, etc you do not have to update every View that has it.
An example of this is the _LogOnPartial that is in a default project. In the _Layout it is called by #Html.Partial("_LogOnPartial"), and the _LogOnPartial view contains a logic statement that either displays LogOn or Register or Welcome back....
The title pretty much states my question.
I have a view (say, Action1) in a controller (Foo) and another view (Action2) in another controller (Bar). In Action1 view, I want to use Html.Partial or Html.RenderPartial to call Action2's view.
I am aware of that I can use Html.RenderAction in Action1, but that will (I think) create the Bar controller and go through the whole controller/action resolution cycle, and I don't want that, as this may be less efficient.
So, my goal is that I want to reuse the Action2's veiw. How can I achieve this?
Consider moving the partial to the Views\Shared folder.
Then you can render it from anywhere:
E.g:
Razor:
#Html.Partial("SharedView")
ASPX:
<%: Html.Partial("SharedView") %>
If you don't want to do that, then pull as much markup from the main partial as you can into a custom display template, then re-use that across the two Views.
And yes, your right about #Html.Action going through the request pipeline, and #Html.Partial not.
In my app I have a need to load the same view from two different controllers without placing the view in the shared views directory.
Basically I have this folder structure
Controllers
EventsController.cs
SearchController.cs
Views
Events
Preview.aspx
Search
basically picture it much the same as here on stack overflow. You get a preview of a bunch of questions under the questions link, but you also get an identically formatted page when you do a search in the search bar. The views and viewmodels are presumably identical.
Since the view I need for search is exactly the same as the view I need for events, I'd like to reuse the same view. I would however like to avoid using the shared directory for this specific view.
So my two part question is ---
Is this possible, and if so how?
Is this bad practice?
Yes, you can. Simply return View("~/Views/Events/Preview.aspx").
However, i would advise against it for a number of reasons. The biggest being that this will be non-obvious to anyone trying to modify the code later (maybe even you) and might lead to potential errors.
A better approach might be to create a "Shared" view, or a shared partial view. My preference would be a shared partial view, then in your non-shared view render the partial view functionality you want.
It's possible.
I am not sure if you are using strong-typed views. But suppose it is, then it is a bit weird for me that you have Event search & Search with same View Model. Possibly separate them with two different view models and view would be better IMHO. Moreover, if you specify the name of view to load in controller, it is somehow considered to be coupling view and controller and it certainly not a good idea.