ASP.NET MVC 2 : Having trouble with creating a Master-Detail View
I'm having trouble right now with the creation of a Master-Detail page in an ASP.NET MVC 2 project at the moment. This project uses Entity Framework OR/M for table mapping. I'm using a custom CategoryModel which is passing another list of objects. I've simplified the Model for presentation purposes :
public class CategoryModel {
public Category Category { get; set; }
public IEnumerable<CategoryDescription> CategoryDescriptions { get; set; }
}
CategoryDescription is a collection of "culture language-based" descriptions for each Category.
I'm passing the CategoryModel to my controller [Again, the controller Edit method has been simplified for presentation purposes] :
// CategoryModel constructor
CategoryModel categoryModel = new CategoryModel()
{
Category = (from c in bo.Categories where c.CategoryID == categoryId select c) as Category,
CategoryDescriptions = bo.CategoryDescriptions.Where(p => p.CategoryID == categoryId).OrderBy(p => p.Language == "en")
};
return View(categoryModel);
After that, I'm sending over the data to my view, which in turn will try to render a PartialView for each CategoryDescription I have. This is where I fail [Only part of the view is shown, the part showing the Category object is just fine] :
<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<InnVue.Globe.Models.CategoryModel>" %>
<%@ Import Namespace="InnVue.Globe.Models" %>
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
<%: ViewContext.RouteData.Values["Action"] %> Category
</asp:Content>开发者_如何转开发
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<h2><%: ViewContext.RouteData.Values["Action"] %> Category</h2>
<% Html.EnableClientValidation(); %>
<% using (Html.BeginForm()) {%>
<%: Html.ValidationSummary(true) %>
<fieldset>
<legend>CategoryDescription</legend>
<% foreach (var catdes in Model.CategoryDescriptions) { %>
<% Html.RenderPartial("CategoryDescriptions", catdes); %>
<% } %>
<% Html.RenderPartial("CategoryDescriptions", Model.CategoryDescriptions, new ViewDataDictionary()); %>
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
<% } %>
<div>
<%: Html.ActionLink("Back to List", "Index") %>
</div>
</asp:Content>
The problem I'm having right now comes from the RenderPartial method, which crash my application every single time I've tried to pass data over it.
I did try to change the Inherits tag to several types, didn't seem to solve the problem. If I don't pass any data using the RenderPartial htmlhelper method, the page loads just fine.
I've tried several suggestions over forum boards, but I couldn't find an answer to solve this problem. The only restriction I have here for pulling the data in the PartialView over is to not use the ViewData[] dictionary from my company for many obvious reasons.
Thanks for your time people, and sorry for my English, I'm a native french speaker from Canada, if any typos sorry in advance !
EDIT 01/10 : The reason why there's one RenderPartial outside the loop is for a new input box for adding description content, but there's logic in the postback edit method of my controller to take care of this. the RenderPartial inside the loop is there to let the user edit existing descriptions of that category. Starting to make the loop work is the key here, I've only made a scaffolded PartialView for test purposes, I can't even load an empty " Hello World
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<InnVue.Globe.Models.CategoryModel>" %>
<% using (Html.BeginForm()) {%>
<%: Html.ValidationSummary(true) %>
<fieldset>
<legend>Fields</legend>
<p>Hello World !</p>
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
<% } %>
<div>
<%: Html.ActionLink("Back to List", "Index") %>
</div>
It appears you are calling the same render partial method twice, passing it once with the datatype CategoryDescription
and another time passing it a model with type IEnumerable<CategoryDescription>
. Have you tried commenting out the one that does not pass the correct data type for the view?
Try something like this:
<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<InnVue.Globe.Models.CategoryModel>" %>
<%@ Import Namespace="InnVue.Globe.Models" %>
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
<%: ViewContext.RouteData.Values["Action"] %> Category
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<h2><%: ViewContext.RouteData.Values["Action"] %> Category</h2>
<% Html.EnableClientValidation(); %>
<% using (Html.BeginForm()) {%>
<%: Html.ValidationSummary(true) %>
<fieldset>
<legend>CategoryDescription</legend>
<% foreach (var catdes in Model.CategoryDescriptions) { %>
<% Html.RenderPartial("CategoryDescriptions", catdes); %>
<% } %>
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
<% } %>
<div>
<%: Html.ActionLink("Back to List", "Index") %>
</div>
</asp:Content>
And use this as your partial view:
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<InnVue.Globe.Models.CategoryModel>" %>
<%: Html.EditorFor(m => m) %>
Thanks NickLarsen for your help, your comment helped me figure out what I was doing wrong.
The inheritance of my partial view was the cause of the problem.
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<InnVue.Globe.Models.CategoryDescription>" %>
Was the solution to my problem, I didn't really understood strongly-typed views, and it led me to wander around aimlessly ^^'
As for the double RenderPartial in my Edit View, this is needed, as I want to have a new field for new data entry no matter if there's already data rows on CategoryDescription or not.
Here's the final fieldset, for those who are wondering how I've done my Master-Detail form :
<fieldset>
<legend>CategoryDescription</legend>
<% foreach (var catdes in Model.CategoryDescriptions) { %>
<% Html.RenderPartial("CategoryDescription", catdes); %>
<% } %>
<%
CategoryDescription emptyCatDes = new CategoryDescription();
Html.RenderPartial("CategoryDescription", emptyCatDes, new ViewDataDictionary()); %>
</fieldset>
I don't know yet if it's 100% effective, but all the information is showing up correctly right now in my View.
Good luck to everyone, thanks again for the help NickLarsen !
精彩评论