partial views in ASP.NET MVC - asp.net-mvc

How create View page which is composed of three partial view pages? I am using ASP.NET MVC
//
// GET: /Partial/
public ActionResult View1()
{
var upit = from i in proba.name
select i;
return PartialView("upit",proba.name);
}
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<h2>Index</h2>
<div><%Html.RenderPartial("View1",proba.name); %></div>
</asp:Content>
Why this code return error: Object reference not set to an instance of an object.

I think you want to use RenderAction, not RenderPartial. View1 is an action, not a view. It returns the partial view, upit. Note that this requires MVC2 (or MVC1 + futures). You also probably want to decorate the action with the ChildActionOnlyAttribute unless you intend to call it from AJAX as well.
[ChildActionOnly]
public ActionResult View1()
{
var upit = from i in proba.name
select i;
return PartialView("upit",proba.name);
}
asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<h2>Index</h2>
<div><%= Html.Action("View1"); %></div>
</asp:Content>
The reason you are getting the specific error is that the proba variable isn't defined in the view, nor does it need to be. In your case, the action determines the model being passed to the partial view so there's no need for any data to be passed. You could only pass it via query parameters anyway when rendering an action.

Inside your view page you would want to make use of the RenderPartial method.
Example
Say I had 3 partial views called "View1", "View2" and "View3". If I wanted to render all 3 of these views to make up the content of my view then I would do something like:
<div id="section1">
<% Html.RenderPartial("View1", Model.Table1) %>
</div>
<div id="section2">
<% Html.RenderPartial("View2", Model.Table2) %>
</div>
<div id="section3">
<% Html.RenderPartial("View3", Model.Table3) %>
</div>
I assume you would have a MasterPage which your view derives from in order to take care of the other necessary markup. The above would just be placed inside the Content section of your derived view.

Related

Partial View is null

I'm learning to use Partial Views in MVC. It's working if I just have some simple text in the Partial View, but when I'm trying to use data from the Model, I get some problem! I guess I'm missing some point and need some guidance.
I'm trying to use a Partial View inside HomeController index file.
The code inside the index file:
<div class="row">
<div class="col-md-3" id="listOfNames">
#Html.Partial("ListPersonLayoutPartialView")
</div>
</div>
And the Partial View:
#model IEnumerable<TestAjaxAutoSuggest.Models.Person>
#foreach (var item in Model) {
<div class="personBlock">#item.Name</div>
}
<p>Test</p>
And finally the action method in the Home controller:
[HttpGet]
public ActionResult ListPersonLayout()
{
return PartialView("ListPersonLayoutPartialView", db.People.ToList());
}
I guess something is missing, like the how the data from the Controller connects to the Partial View!?
You need to use Html.Action here not Html.Partial,if you want to render partial view Html.Partial then you have to pass Model as well from Main view, which are not passing, so Model is null and additionally Html.Partial does not call action, for calling action you have use Html.Action which will in return renders partial view:
#Html.Action("ListPersonLayout")
you need to understand difference of these two, for that you can see this post
You should call ListPersonLayout and not ListPersonLayoutPartialView as follows:
<div class="row">
<div class="col-md-3" id="listOfNames">
#Html.Partial("ListPersonLayout")
</div>
</div>

ASP.NET MVC - MasterPage cannot be applied to this page because the control collection is read-only. If the page contains code blocks

This error message doesn't make a lot of sense in the context of MVC:
MasterPage cannot be applied to this page because the control collection is read-only. If the page contains code blocks, make sure they are placed inside content controls (i.e. <asp:Content runat=server />)
What's it mean?
My view looks something like this:
<%# Page Inherits="System.Web.Mvc.ViewPage<Site.Controllers.ProductCategoryController.ProductListViewModel>" MasterPageFile="~/site.master" %>
<% foreach (var prod in Model.Products) { %>
<li><%=prod.Description%></li>
<% } %>
I figured it out, it is quite a simple mistake. The problem was my view code wasn't wrapped in a content control (which maps to a contentplaceholder in the master page).
Of course my view should be like this:
<%# Page Inherits="System.Web.Mvc.ViewPage<Site.Controllers.ProductCategoryController.ProductListViewModel>" MasterPageFile="~/site.master" %>
<asp:Content runat="server" ID="Content1" ContentPlaceHolderID="BodyContent">
<% foreach (var prod in Model.Products) { %>
<li><%=prod.Description%></li>
<% } %>
</asp:Content>
Pretty obvious but I just couldn't see it!
And the error message didn't really help me.

Automatically rendering shared view as part of master page?

I have a shared view located in Shared/Header.aspx and I want to render this as part of the HeaderContent ContentPlaceHolder. My master page contains:
<asp:ContentPlaceHolder ID="HeaderContent" runat="server" />
and I want to be able to tell MVC to populate that content place holder with the Shared/Header view, which contains:
<%# Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %>
<asp:Content ID="Content1" ContentPlaceHolderID="HeaderContent" runat="server">
....
</asp:Content>
At the moment in each of the pages where I want the HeaderContent to be populated (and on some pages I don't want it to be) I do this:
<asp:Content ID="Content2" ContentPlaceHolderID="HeaderContent" runat="server">
<% Html.RenderPartial("Header"); %>
</asp:Content>
Is there any way I can effectively do the above but from the Controller handling the request (or a child class of ViewPage)?
If you want to do this from the controller, then you could pass a property in the ViewData, which could be picked up from the layout page. E.g. in a controller action:
ViewData["ShowHeader"] = true;
Then in the layout page you could say
<% if(ViewData["ShowHeader"] != null && ((bool)ViewData["ShowHeader"]))
{
Html.RenderPartial("Header");
} %>
That way you don't need the extra content placeholder too.

Client side validation script is not generated for partial views fetched using AJAX

I am trying to setup client side validation using MicrosoftMvcJQueryValidation
to work with ajax submitted forms.
It works perfectly fine if the partial view is rendered directly from a view.
However when I try to fetch it over XHR, for example to show it in a JQuery Dialog,
client validation javascript is not generated for the output html.
Any ideas?
Working code - partial view is rendered using Html.RenderPartial:
View:
<%# Page Title="" Language="C#" Inherits="System.Web.Mvc.ViewPage<dynamic>" %>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<% Html.RenderPartial("New"); %>
</asp:Content>
Partial View:
<%# Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<Product>" %>
<% Html.EnableClientValidation();%>
<% Html.BeginForm();%>
<%= Html.EditField(m => m.price)%>
<%= Html.ValidationMessageFor(m => m.price)%>
<% Html.EndForm();%>
Not working code - partial view is fetched with JQuery load() function.
View:
<%# Page Title="" Language="C#" Inherits="System.Web.Mvc.ViewPage<dynamic>" %>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
....
$("#dialog").load('~/Product/New/');
$("#dialog").dialog("open");
....
<div id="dialog" title=""></div>
</asp:Content>
Relevant controller action:
public PartialViewResult New(int id)
{
return PartialView(service.GetProduct());
}
Thanks.
This will happen for all partial views which return JavaScript inserted into the DOM via AJAX. The problem is that the JavaScript returned with the partial view is not executed/interpreted when it is inserted into the document.
Unfortunately, because what you are dealing with is generated JavaScript I can explain why you are experiencing the problem but I'm at a loss for a solution. Were this a function you wrote I'd suggest adding it to the OnComplete. All I can offer is that this is a JavaScript limitation and to start looking there.
BTW: this looks promising http://adammcraventech.wordpress.com/2010/06/11/asp-net-mvc2-ajax-executing-dynamically-loaded-javascript/
After reading the blog ARM has mentioned it seems the solution really depends
on how one is loading the partial view.
What eventually worked for me is to call __MVC_EnableClientValidation
after view has been assigned to an element:
$.get('~/Product/New/', function(data) {
$("#dialog").html(data);
// extracted from MicrosoftMvcJQueryValidation.js
var allFormOptions = window.mvcClientValidationMetadata;
if (allFormOptions) {
while (allFormOptions.length > 0) {
var thisFormOptions = allFormOptions.pop();
__MVC_EnableClientValidation(thisFormOptions);
}
}
},'html');

SelectList, ASP.NET MVC

I'm working with a SelectList, and populating it with the data from a table. I'm trying to bind it to the ID of another object.
EDIT
Updated the Schema to Reflect something I neglected. I have updated it to show the exact names of each item. I think the problem comes in the fact that each Unit has a sheet, and each sheet has a product. (The sheet will hold more information for the product, but a Unit will have a great deal of other information, so I wanted to separate them in order to keep it clear what was what.)
I think something is happening and the "Sheet" isn't being initialized as an object, and when the binding occurs, it doesn't have an object to bind to, since it is one-level deep. Tell me if this makes sense, or if I am just completely off base.
**Unit**
UnitID (PK)
**ProductSheet**
UnitId (FK)(PK)
ItemId (FK)
**Items**
ItemId (PK)
ItemTitle
It just ...isn't working though. I have this code.
DatabaseDataContext db = new DatabaseDataContext();
Unit unit = new Unit();
ViewData["Items"] = new SelectList( db.Items, "Id", "ItemTitle", unit.ProductSheet.ItemId);
But in the postback, the selectList is always null and empty! This is the View code. I'm really getting lost here, I've followed a lot of examples and it still comes up with bunk.
<%= Html.DropDownList("Items") %>
Your view code should read:
<% var selectItems = ViewData["Items"] as SelectList; %>
<%= Html.DropDownList("ProductSheet.ItemId", selectItems) %>
An entire sample of the project is available at this url
These are the action methods.
public ActionResult Create()
{
DatabaseDataContext database = new DatabaseDataContext();
Unit u = new Unit();
u.Sheet = new Sheet();
ViewData["ProductListing"] = new SelectList(database.Products, "ProductId", "ProductName", u.Sheet.ProductId);
return View();
}
//
// POST: /Home/Create
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Create(Unit u)
{
try
{
DatabaseDataContext database = new DatabaseDataContext();
database.Units.InsertOnSubmit(u);
database.SubmitChanges();
// TODO: Add insert logic here
return RedirectToAction("Index");
}
catch
{
return View();
}
}
Here is the Create View.
<%# Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<MVC.Models.Contexts.Unit>" %>
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
Create
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<h2>Create</h2>
<%= Html.ValidationSummary("Create was unsuccessful. Please correct the errors and try again.") %>
<% using (Html.BeginForm()) {%>
<fieldset>
<legend>Fields</legend>
<%= Html.DropDownList("ProductListing") %>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
<% } %>
<div>
<%=Html.ActionLink("Back to List", "Index") %>
</div>
</asp:Content>
<asp:Content ID="Content3" ContentPlaceHolderID="ScriptContent" runat="server">
</asp:Content>
I've marked the answer that seems to have made some progress now, I think I'm starting to understand it better.
When I passed the 'path' of the object to assign as a string in the name field of DropDownList, it seems to work. But this doesn't really make a lot of sense to me. Can you explain what is going on any better?

Resources