Is there a way to render inside my view of controller A a partial view from other controller B?
Edit: I wrote a partial view that is good for only two controllers and I don't want to copy it to their both Views folder.
I want The partial view to be displayed each time the View is rendered not after something happens.
You can share views between controllers by putting them into the Views/Shared folder. Each controller can then render that view by name.
You can render a partial view (which can be shared between controllers as in (1)) within the current view using Html.Partial().
You can use Html.Action() to invoke an action on a different controller and render the results within the current view.
You can use AJAX to load a partial view from a different controller after the page has been rendered.
#Html.Partial("~/Views/ControllerB/Index.cshtml")
Yes,
return PartialView("/path/view.cshtml");
You just need to work out the path part.
Alternatively you can put the partial view in views/shared then just return :
return PartialView("view.cshtml");
#model YourModelNamesapce.ModelName
#{
ViewBag.Title = "Edit";
Layout = "~/Views/Shared/_LayoutForPartialViews.cshtml";
}
<table>
<tr>
<td>
#Html.LabelFor(model => model.fieldname)
</td>
<td>
#Html.DisplayFor(model => model.fieldname)
</td>
</tr>
<tr>
<td>#Html.Action("PartialViewAction", "Controller", new { id = Model.id })</td>
</tr>
</table>
Just a side note as i found this thread searching for the same question but the answers weren't working: in Orchard CMS modules you cannot use the neat solution posted by Pittfall, you have to use relative paths to return partial views. Lets say you have a controller
Controllers/SiteController.cs
and you want to return the partial view
Shared/MessageList/Items
then in your action methods you need to write
return PartialView("../Shared/MessageList/Items");
Related
The goal is to have one page with a wizard. Each step of the wizard is a partial view containing a form. I have only one controller (Insurance) with an action for each view. The actions receive the posted data and return the viewmodel for the next step, or the viewmodel of the current step containing the error details.
The page (Index.cshtml) has partial views, rendered as
#Html.Partial("~/Views/Shared/_RegistrationCode.cshtml")
and the partial view itself contains a form, rendered as
#using (Html.BeginForm("RegistrationCodeDetails", "Insurance", FormMethod.Post)) {
and a
<input type="submit" name="nextButton" value="Verder" class="btn btn-success" />
within the form to submit it.
The code works as intended up to the point where the first action returns the viewmodel for the next step (partial view _Product) using
return PartialView("_Product", productViewModel);. The ActionResult is not sent to the partial view, but rendered as a full view, so the result is a partial being rendered as the only thing on the screen.
I've fiddled with #using (Ajax.BeginForm("RegistrationCodeDetails", "Insurance", new AjaxOptions { UpdateTargetId = "articleProductOutput", HttpMethod = "Post" })) { but the data is not rendered in the second wizard step partial.
Edit:
We've decided to take a different approach: One page, one controller and basically one viewmodel. The initial data is rendered right away, data depending on other steps in the wizard is retrieved using JSON and partial views.
Unless you mark your partial view as [ChildActionOnly], it won't load in the same page!
you Partial view should look like
[ChildActionOnly]
public ActionResult _ParialView1()
{
//TODO: Add the required code here
}
//and your PartialView should be included in the main view as :
#{Html.Action("_PartialView1","Controller1");}
Thanks and hope this helps!
Taken from index.cshtml:
#model MvcMovie.Models.Movie
#{
ViewBag.Title = "Details";
}
<h2>Details</h2>
<fieldset>
<legend>Movie</legend>
<div class="display-label">
Why does Visual Studio's MVC template set ViewBag.Title in views rather than in the corresponding controllers?
In my opinion, any setting should be done in the controller and any getting should be done in the view. What do you think of it?
Because the value of ViewBag.Title is then used in the Layout file \Views\Shared\_Layout.cshtml:
<title>#ViewBag.Title</title>
To expand on Fabio S' answer - because the <title> is a presentation concept. I think that it is a good guide to have setting done in controller (or business logic) and getting done in view, but more important is for the views to be concerned with presentation and the controllers to be the control and intermediary between the views and the models and business logic. If I want to see where the title of the final html page is set I would find it more intuitive to look in the view rather than the controller as I think of title as a presentation concept.
its on the coder to decice what action method return what views.. so your controller OR Action method might just return a JSON object or an HTTPResponseCode in that case there is no point setting the title inside the controller or action method..
its ultimately is a presentation thing as you might also not want to display to say Create on a view that creates your entity instead you might wanna say Create which now depends upon the action method and the controller.
Currently I have a partial view where I manually display all my blog categories with links. I would like to make it dynamic by pulling from the database. I am not sure how to accomplish this within a partial view. I would even be willing to do it within the actual _layout page if it's easier that way.
Here is what I have right now.
_Categories.cshtml
<h2>Categories</h2>
<hr/>
<p>
ASP.Net MVC<br/>
Ruby on Rails<br/>
</p>
I would like to create these links dynamically as opposed to hard coding.
_Layout.cshtml
#Html.Partial("_Categories")
The main problem is there is no controller for the layout of a partial which is why I can't figure out how to go about it.
Thanks in advance for any help.
Create a controller action named ListCategories in BlogController (or in a new CategoryController). Add all the categories to the ViewBag in the action by querying them from your back-end database
public ActionResult ListCategories()
{
ViewBag.Categories = db.Categories;
}
And use a #foreach loop in the view for the action ListCategories.cshtml:
<h2>Categories</h2>
<hr/>
<p>
#foreach(Category c in ViewBag.Categories)
{
#c.Name<br/>
}
</p>
Finally, change your _Layout.cshtml to point to this action:
#Html.Action("ListCategories")
// or #Html.Action("ListCategories", "CategoryController")
In my forum project I have a partial view (.ascx) that is used for adding a new forum post. Forum posts live inside Topics (Categories) and both these tables have a column named Title.
Now the problem is that when I place the partial view on a Topic page, it automatically grabs the Title value from the Topic, thus populating my Title Textbox with the Topic Title. Not ideal!
The code inside the CreatePost.ascx is simply
<label for="Title">Title</label>
<%= Html.TextBox("Title") %>
I've tried changing that to <%= Html.TextBox("Post.Title") %> but then the Textbox value doesn't get posted.
Is this normal behaviour, and is there a way I can get rid of it without clearing it with Javascript?
I've even tried setting a value using the 2nd overload Html.TextBox("Title", "some value") but that just gets overridden.
Please help!
If you are using ASP.NET MVC 2 you should always use strongly typed helpers which will correctly handle binding:
<%= Html.TextBoxFor(x => x.Category.Title) %>
Try the following:
CreatePost.ascx
<label for="Title">Title</label>
<%= Html.TextBox("Title") %>
YourController.cs
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult CreatePost(string Title) {
// do something with Title
return View();
}
Need to make sure CreatePost.ascx is being rendered between
<% using (Html.BeginForm()) { %>....
..
<% Html.RenderPartial("CreatePost.ascx");
..
..
<% } >
in your View.
Hope this helps...
It sounds like the issue is with the code you are using to render the partial view. RenderPartial will be default pass through the model from the parent view, hence the behaviour you are seeing when the Topic title is displayed in the partial. You can override this though - one of the parameter of RenderPartial allow you to pass in a new model.
Something like:
<% Html.RenderPartial("CreatePost.ascx", new Post());%>
to pass in a new model to the partial view (in this case an empty Post).
Background:
I'm trying to produce dynamically generated Factsheets, where each Factsheet has a number of ContentAreas, and each ContentArea is configured to contain a number of Panels.
I have a FactsheetController, a ContentAreaController, a PanelController and individual panels such as NameAndDate and AssetPanel
FactsheetController produces an Index View which acts as a template to load ContentAreas in to.
This is FactsheetController's Index, where Model contains the configuration data defining which panels are associated with which ContentArea:
<div id="divTop">
<% Html.RenderAction("Top", "ContentArea", Model); %>
</div>
<div id="divLeftColumn">
<% Html.RenderAction("Left", "ContentArea", Model); %>
</div>
<div id="divRightColumn">
<% Html.RenderAction("Right", "ContentArea", Model); %>
</div>
<div id="divBottom">
<% Html.RenderAction("Bottom", "ContentArea", Model); %>
</div>
When the Top action method gets called on ContentAreaController, it passes a list of PanelConfigurations associated with that ContentArea to its PartialView, which is defined as:
<% foreach (ConfiguredFactsheetPanel panel in Model)
{ %>
<% Html.RenderAction(panel.Name, "Panel", panel); %>
<% } %>
This PartialView renders then renders each panel that it is configured to show.
When I'm loading the FactsheetController I need an instance of a Fund object to know which ContentAreas are associated with that particular Factsheet, so I create one based on QueryString data. The thing is, I also need that Fund object in the PanelController because the Fund object contains the data I need to display. That QueryString data doesn't exist in the PanelController, because it only existed in the URL that called FactsheetController.
question:
So my question is, what's the best way for me to make the Fund object I create in FactsheetController to be available in the PanelController
I'd also be interested in hearing anyone's opinion on issues with this initial design.
I wouldn't use query strings like that. I would extend the model object passed to FactsheetController's Index to include the data required in your other partial views and then pass that to the actions with the RenderAction method. So ConfiguredFactsheetPanel would be extended to either contain, or be replaced by a type that contained, the Fund object you require in your partial views.
I suspect that the objects that you are using in your view currently are entities driven by your persistence technology such as NHibernate or Entity Framework. If this is the case you probably won't want to change your entity definitions to satisfy your views and instead create view models.