Model Binding not working with mvc1
We have very large object called FoodFormViewModel. We go to add page like
FoodFormViewModel foodFormViewModel = new FoodFormViewModel();
return View("Edit", foodFormViewModel);
But when we come to post method like
[AcceptVerbs(HttpVerbs.Post)]
[ValidateInput(false)]
public ActionResult Edit(FoodFormViewModel objViewModel)
{
SaveProcess(objViewModel);
return View(objViewModel);
}
Our objViewModel properties are all blank. Our FoodFormViewModel definition is
#region Properties
public MealPlannerDataManager MPManager { get; set; }
public Food Food { get; set; }
public SelectList FoodGroupLevel1 { get; set; }
public SelectList FoodGroupLevel2 { get; set; }
public SelectList FoodGroupLevel3 { get; set; }
public SelectList FoodType { get; set; }
public SelectList Company { get; set; }
public SelectList Brand { get; set; }
public SelectList NutritionSource { get; set; }
public SelectList DataSource { get; set; }
public SelectList PlannerSource { get; set; }
public SelectList PublishMonth { get; set; }
public SelectList PublishDay { get; set; }
public SelectList PublishYear { get; set; }
public SelectList TagTypes { get; set; }
public List<CheckBoxInfo> MealTime { get; set; }
public List<CheckBoxInfo> Condition { get; set; }
public List<CheckBoxInfo> Allergens { get; set; }
public List<CheckBoxInfo> Occasions { get; set; }
public List<CheckBoxInfo> Others { get; set; }
public List<CheckBoxInfo> SpecialDiet { get; set; }
public List<CheckBoxInfo> Course { get; set; }
public List<CheckBoxInfo> PrepMethod { get; set; }
public List<CheckBoxInfo> Season { get; set; }
public List<CheckBoxInfo> SkillLevel { get; set; }
public List<CheckBoxInfo> Cuisine { get; set; }
public List<CheckBoxInfo> MealPlan { get; set; }
public List<CheckBoxInfo> Products { get; set; }
public List<CheckBoxInfo> AgeGroup { get; set; }
public FoodNutritionInfo NutrInfo { get; set; }
public FoodNutritionInfo AltNutrInfo { get; set; }
Tag dummyTag = new Tag();
TagType dummyTagType = new TagType();
#endregion Properties
WE couldn't figure out the issue. Any help is highly appreciated. We are using MVC1 with VS 2008
My view contains 3-4 partial views, i am posting one of the partial view here
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<MealPlannerAdmin.Models.ViewModel.FoodFormViewModel>" %>
<%@ Import Namespace="MealPlannerAdmin.Models.Objects.HTMLHelpers" %>
<%@ Import Namespace="MealPlanner.BusinessObjects.Model" %>
<div id="ValidationSummary" style="position: absolute; margin: 110px 0px 0px 620px;
width: 350px; height: 359px; overflow: auto; border: 0px">
<%=Html.ValidationSummary("Please review all tabs for following errors") %>
</div>
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tbody>
<tr>
<td colspan="2">
<div id="foobar" style="color: Red;">
<%=ViewData["CloningMessage"]%></div>
</td>
</tr>
<tr>
<td colspan="2" class="comHead">
<strong>Food Basic Information</strong>
</td>
</tr>
<tr>
<td colspan="2">
<div id="divCloningMessage" class="errMsg">
</div>
</td>
</tr>
<tr>
<td colspan="2">
<div id="divBtnCloneThisFood" style="display: none;">
<input type="button" value="Clone this Food" id="btnCloneThisFood" name="btnCloneThisFood" />
</div>
</td>
</tr>
<tr>
<td width="200" valign="top">
<span id="spanOriginalCreatorLabel"></span>
</td>
<td>
<span id="spanOriginalCreator"></span>
</td>
</tr>
<tr>
<td width="200" valign="top">
<span id="spanClonedByLabel"></span>
</td>
<td>
<span id="spanClonedBy"></span>
</td>
</tr>
<tr>
<td width="200" valign="top">
<label for="lblFoodID">
Food ID:
</label>
</td>
<td>
<span id="spanFoodID" name="spanFoodID">
<%=Model.Food.FoodID%></span>
</td>
</tr>
<tr>
<td valign="top">
<label for="ddlFoodGroupLevel1">
Food Group Level 1: *</label>
</td>
<td>
<%=Html.DropDownList("ddlFoodGroupLevel1", Model.FoodGroupLevel1, new { @class = "dropdown"})%> <%=Html.ValidationMessage("FoodGroupLevel1", "*")%>
</td>
</tr>
<tr>
<td valign="top">
<label for="ddlFoodGroupLevel2">
Food Group Level 2 :
</label>
</td>
<td>
<%=Html.DropDownList("ddlFoodGroupLevel2", Model.FoodGroupLevel2, new { @class = "dropdown" })%> <%=Html.ValidationMessage("FoodGroupLevel2", "*")%>
</td>
</tr>
<tr>
<td valign="top">
<label for="ddlFoodGroupLevel3">
Food Group Level 3:
</label>
</td>
<td>
<%=Html.DropDownList("ddlFoodGroupLevel3", Model.FoodGroupLevel3, new { @class = "dropdown" })%>
</td>
</tr>
<tr>
<td valign="top">
<label for="Food.FoodName">
Food Name: *</label>
</td>
<td>
<%=Html.TextBox("FoodName", Model.Food.FoodName, new { @maxlength = "250" })%> <%=Html.ValidationMessage("FoodName", "*")%>
</td>
</tr>
<tr>
<td valign="top">
<label for="FoodDisplayName">
Food Display Name: *</label>
</td>
<td>
<%=Html.TextBox("FoodDisplayName", Model.Food.FoodDisplayName, new { @maxlength = "250" })%> <%=Html.ValidationMessage("FoodDisplayName", "*")%>
</td>
</tr>
<tr>
<td valign="top">
<label for="ddlFoodType">
Food Type: *</label>
</td>
<td>
<%=Html.DropDownList("ddlFoodType", Model.FoodType, new { @class = "dropdown" })%> <%=Html.ValidationMessage("FoodType", "*")%>
</td>
</tr>
<tr id="rowCompany">
<td valign="top">
<label for="ddlCompany">
<span id="spanCompany" name="spanCompany"></span>
</label>
</td>
<td>
<%=Html.DropDownList("ddlCompany", Model.Company, new { @class = "dropdown" })%> <%=Html.ValidationMessage("Company", "*")%>
</td>
</tr>
<tr id="rowAddCompany">
<td>
</td>
<td>
<table border="0" cellpadding="0" cellspacing="0">
<tr>
<td colspan="2" valign="top" class="subHead">
<label for="txtAddCompany">
<span id="spanAddCompany" name="spanAddCompany"></span>
</label>
</td>
</tr>
<tr>
<td>
<%=Html.TextBox("txtAddCompany", string.Empty, new { @id = "txtAddCompany", @maxlength = 100, @boundButton = "btnNewCompany", @catId = Convert.ToInt16(EntityConstants.TagType.Company), @catName = EntityConstants.TagType.Company, @updateEle = "divAgeGroup", @uiUpdateType = "drop-down-list" })%>
<div id="divAddCompanyError" boundbutton="btnNewCompany" class="errHidden">
</div>
<div id="<%=EntityConstants.TagType.Company %>Message" style="display: none; color: Red;">
</div>
</td>
<td>
</td>
</tr>
<tr>
<td>
<%=Html.TextArea("txtAddCompanyDesc", string.Empty, 5, 42, new { @id = "txtAddCompanyDesc", @class = "text-area-classic w374px", @boundButton = "btnNewCompany" })%>
</td>
<td valign="bottom">
<input type="button" value="Add" id="btnNewCompany" />
</td>
</tr>
</table>
</td>
</tr>
<tr>
<td valign="top">
<label for="cblMealTime">
Meal Time:</label>
</td>
<td>
<table border="0" cellpadding="0" cellspacing="0">
<tr>
<td>
<%=Html.CheckBoxGrid("cblMealTime", Model.MealTime, 4) %>
</td>
<td>
<%=Html.ValidationMessage("Meal", "*")%>
</td>
</tr>
</table>
</td>
</tr>
<tr>
<td valign="top">
<label for="ddlNutritionSource">
Nutrition Source: *</label>
</td>
<td>
<%=Html.DropDownList("ddlNutritionSource", Model.NutritionSource, new { @class = "dropdown" })%> <%=Html.ValidationMessage("NutritionSource", "*")%>
</td>
</tr>
<tr>
<td valign="top">
<label for="ddlDataSource">
Data Source: *</label>
</td>
<td>
<%=Html.DropDownList("ddlDataSource", Model.DataSource, new { @class = "dropdown" })%> <%=Html.ValidationMessage("DataSource", "*")%>
</td>
</tr>
<tr>
<td valign="top">
<label for="Display">
Display: *</label>
</td>
<td>
<%=Html.RadioButton("Display", true, Model.Food.Display, new { @id = "DisplayTrue" })%><label>Yes</label>
<%=Html.RadioButton("Display", false, !(Model.Food.Display), new { @id = "DisplayFalse" }) %><label>No</label>
</td>
</tr>
<tr>
<td valign="top">
<label for="Issue">
Issue: *</label>
</td>
<td>
<%=Html.RadioButton("Issue", true, Model.Food.Issue, new {@id="IssueTrue", @onclick= "disableIssueText()"})%><label>Yes</label>
<%=Html.RadioButton("Issue", false, !(Model.Food.Issue), new {@id="IssueFalse", @onclick = "disableIssueText()" })%><label>No</label>
</td>
</tr>
<tr>
<td valign="top">
<label for="IssueDescription">
Describe Issue:
</label>
</td>
<td>
<%=Html.TextArea("IssueDescription", Model.Food.IssueDescription, 4, 75, new { @maxlength = "50", @class = "w500px" })%>
</td>
</tr>
<tr>
<td valign="top">
<label for="FoodDescription">
Description:</label>
</td>
<td>
<%=Html.TextArea("FoodDescription", Model.Food.FoodDescription, 5, 40, new { @maxlength = "50" })%> <%=Html.ValidationMessage("FoodDescription", "*")%>
</td>
</tr>
<tr>
<td valign="top">
<label for="Tags">
Tags:</label>
</td>
<td>
<%=Html.TextArea("Tags", Model.Food.Tags, 5, 40, new { @maxlength = "50" })%> <%=Html.ValidationMessage("Tags", "*")%>
</td>
</tr>
<tr>
<td valign="top">
<label for="Image">
Image:</label>
</td>
<td>
<table>
<tr>
<td>
<%=Html.Image("Img200x200", Model.Food.Img200x200, "Food Image", new { @width = "200", @height = "200" })%>
</td>
</tr>
<tr>
<td>
<div id="browseFile">
<input name="Image" id="Image" type="file" size="45" onchange="document.getElementById('inputTxtFake').value = this.value;"
class="inputImage" />
<!-- fake input to display the path of the selected file : start -->
<input name="inputTxtFake" type="text" id="inputTxtFake" />
<!-- fake input to display the path of the selected file : end -->
</div>
<input id="ClonedFromFoodID" name="ClonedFromFoodID" type="hidden" value="<%=Model.Food.ClonedFromFoodID %>" />
<input id="IsUserFood" name="IsUserFood" type="hidden" value="<%=Model.Food.IsUserFood %>" />
<input id="Img200x200" name="Img200x200" type="hidden" value="<%=Model.Food.Img200x200 %>" />
</td>
</tr>
</table>
</td>
</tr>
</tbody>
</table>
<script language="javascript" type="text/javascript">
$(document).ready(function() {
var isUserFood = '<%=Model.Food.IsUserFood %>';
var hasClones = '<%=Model.Food.HasClones %>';
var isClone = '<%=Model.Food.IsClone %>';
var canClone = window.location.toString().toLowerCase().indexOf("/edit") > -1;
var gettingCloned = window.location.toString().toLowerCase().indexOf("/clone") > -1
if (hasClones.toLowerCase() == 'tr开发者_Python百科ue') {
$("#divCloningMessage").html("This food has already been cloned.");
canClone = 'false';
}
originalCreator = '<%=Model.Food.OriginalCreator%>';
clonedFromFoodID = '<%=Model.Food.ClonedFromFoodID%>';
$("#spanOriginalCreatorLabel").html("Original Creator:");
$("#spanOriginalCreator").html(originalCreator);
if (isClone.toLowerCase() == 'true') {
var originalCreator;
$("#spanClonedByLabel").html("Cloned By:");
$("#spanClonedBy").html("WFM Nutritionist");
$("#divCloningMessage").html("This food is cloned from food with id " + clonedFromFoodID + ".");
canClone = 'false';
}
if (canClone == true) {
utility.ui.makeYUIButton("btnCloneThisFood");
$("#btnCloneThisFood-button").click(function() {
var cloneFoodId = '<%=Model.Food.FoodID %>';
var clonedFoodUrl = '<%=Url.Content("~/") %>foods/clone/' + cloneFoodId;
window.location = clonedFoodUrl;
});
$("#divBtnCloneThisFood").show();
}
var clonedFromFoodID = $("#ClonedFromFoodID").val();
if (gettingCloned) {
$("#spanFoodID").html("0");
}
utility.ui.makeYUIButton("btnNewCompany");
checkForBasicFood();
$("#ddlFoodType").change(function() {
checkForBasicFood();
});
$("#btnNewCompany").click(function() {
var btnID, txtNameId, txtDescId, catId, catName, eleToUpdateId, uiUpdateType;
btnID = "btnNewCompany";
txtNameId = $("input[boundbutton='" + btnID + "']").attr('id');
txtDescId = $("textarea[boundbutton='" + btnID + "']").attr('id');
catId = $("input[boundbutton='" + btnID + "']").attr('catId');
eleToUpdateId = $("input[boundbutton='" + btnID + "']").attr('updateEle');
catName = $("input[boundbutton='" + btnID + "']").attr('catName');
uiUpdate = $("input[boundbutton='" + btnID + "']").attr('uiUpdateType');
if ($("#" + txtNameId).val() == "")
$("div[boundButton='" + btnID + "']").fadeIn().fadeOut(10000);
else {
var subCategory = {
categoryId: catId,
parentCategoryId: $("#ddlFoodType").val(),
categoryLevel: 2,
categoryName: $("#" + txtNameId).val(),
categoryDescription: $("#" + txtDescId).val(),
categoryIconPath: "",
sortOrder: 0
};
// Initializing food helper
foodHelper.init('<%= Url.Content("~/") %>');
foodHelper.addSubCategory(subCategory, {
updateElementId: eleToUpdateId,
updateDropdownID: "ddlCompany",
categoryName: catName,
messageDivId: catName + "Message",
catNameTxtBoxId: txtNameId,
catDescTxtBoxId: txtDescId,
uiUpdateType: uiUpdate
});
}
});
});
function checkForBasicFood() {
if ($("#ddlFoodType").val() == 1444 || $("#ddlFoodType").val() == -1) { // Bad: hard coding value
$("#rowCompany").hide();
$("#rowAddCompany").hide();
}
else {
var selectedFoodType = $("#ddlFoodType").val();
if (selectedFoodType == 688) {
$("#spanCompany").html("Restaurant Brand:");
$("#spanAddCompany").html("Add a New Restaurant Brand:");
$("#divAddCompanyError").html("Please enter name for Restaurant Brand.");
}
else if (selectedFoodType == 689) {
$("#spanCompany").html("Store Brand:");
$("#spanAddCompany").html("Add a New Store Brand:");
$("#divAddCompanyError").html("Please enter name for Store Brand.");
}
$("#rowCompany").show();
$("#rowAddCompany").show();
}
}
</script>
Personally, I think it is very odd to have properties of type SelectList
and List<CheckBoxInfo>
in your view model class. Most viewmodels should contain properties of very basic types, like string
and int
. The way you have, makes it very hard to debug & identify your problems but I would go and say that most likely the default model binder doesn't know how to bind values from HTML controls to your viewmodel props.
I would advise looking into building a custom modelbinder or rewriting the view model class. Or rewriting the app as a whole (but I guess that's not an option).
HTH
Certain property name don't match with actual names............need to modify
精彩评论