表单提交时,ViewModel为null

时间:2012-04-30 12:40:13

标签: c# asp.net-mvc-3 viewmodel

我要做的是创建一个SubCategory对象。为了做到这一点,我创建了一个viewmodel,它将为我的视图提供nescesarry数据(包括子类别将绑定的类别对象。)

当我发布我的表单时,viewmodel会返回到我的控制器,但是我的子类别的所有属性和我从下拉列表中选择的值都是null。

我在做错了什么? :S

视图:

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.master" Inherits="System.Web.Mvc.ViewPage<SkyLearn.Areas.Categories.Models.CategoryViewModel>" %>

<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
    Create
</asp:Content>

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">

<h2>Create</h2>

<script src="<%: Url.Content("~/Scripts/jquery.validate.min.js") %>" type="text/javascript"></script>
<script src="<%: Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js") %>" type="text/javascript"></script>

<form action="" method="post" enctype="multipart/form-data">
    <%: Html.ValidationSummary(true) %>
    <fieldset>
        <legend>SubCategory</legend>

        <div class="editor-label">
            <%: Html.LabelFor(model => model.subcategory.Title) %>
        </div>
        <div class="editor-field">
            <%: Html.EditorFor(model => model.subcategory.Title)%>
            <%: Html.ValidationMessageFor(model => model.subcategory.Title)%>
        </div>

        <div class="editor-label">
            <%: Html.LabelFor(model => model.subcategory.Icon)%>
        </div>
        <div class="editor-field">
            <input type="file" name="icon" id="icon"/>
        </div>

        <%: Html.DropDownListFor(selectedcategory => Model.selectedCategory, Model.categories) %>

        <div class="editor-label">
            <%: Html.LabelFor(model => model.subcategory.Description)%>
        </div>
        <div class="editor-field">
            <%: Html.EditorFor(model => model.subcategory.Description)%>
            <%: Html.ValidationMessageFor(model => model.subcategory.Description)%>
        </div>

        <p>
            <input type="submit" value="Create" />
        </p>
    </fieldset>
</form>

<div>
    <%: Html.ActionLink("Back to List", "Index") %>
</div>

</asp:Content>

<asp:Content ID="Content3" ContentPlaceHolderID="SideContent" runat="server">
</asp:Content>

控制器:

[Authorize(Roles = "administrator")]
        [HttpPost]
        public ActionResult Create(CategoryViewModel viewmodel, HttpPostedFileBase Icon)
        {
            SubCategory subcategory = viewmodel.subcategory;

            subcategory.Category = categorycontroller.getCategoryByName(viewmodel.selectedCategory);

            if (Icon != null && Icon.ContentLength > 0)
            {
                // extract only the filename
                var fileName = Path.GetFileName(Icon.FileName);
                // store the file inside ~/App_Data/uploads folder
                var path = Path.Combine(Server.MapPath("../../Content/icons/"), fileName);
                Icon.SaveAs(path);
                subcategory.Icon = fileName;
            }

            if (ModelState.IsValid)
            {
                db.subcategories.Add(subcategory);
                db.SaveChanges();
                return RedirectToAction("Index");  
            }

            return View(subcategory);
        }

视图模型:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data.Entity;
using System.Web.Mvc;

namespace SkyLearn.Areas.Categories.Models
{
    public class CategoryViewModel
    {
        public List<SelectListItem> categories;
        public SubCategory subcategory;
        public string selectedCategory;

        public CategoryViewModel()
        {
            categories = new List<SelectListItem>();
            subcategory = new SubCategory();
            selectedCategory = "";
        }
    }
}

viewmodel包含我尝试创建的子类别可以绑定到的类别列表。它还包含一个子类别对象,我可以用来创建子类别。最后一个属性是我想用来绑定下拉列表中的选项的字符串。

1 个答案:

答案 0 :(得分:1)

ASP.Net MVC3的SelectListItem表现不像你期望的那样。另外,尝试使用Html.DropDownListFor()而不是Html.EditorFor()来制作下拉列表。

在ViewModel中:

public IList<string> PossibleValues {get; set;}
public string SelectedValue {get; set;}

将值加载到ViewModel构造函数中的PossibleValues中。

在视图中

@Html.DropDownListFor(x => x.SelectedValue, new SelectList(Model.PossibleValues))

这将自动生成您的下拉列表并将其绑定到您的模型。如果需要,您也可以将默认值和其他自定义设置传递给此Html帮助程序函数。

保存其他值 您可以保存其他值,用户不应该选择编辑这些值,但如果用户进行编辑,那么这些值不是任务关键,

@Html.HiddenFor(m => m.RememberThisValue);

请记住,此值在显示中隐藏,但仍可在DOM上进行编辑,并根据用户的需要进行发布。确保通过检查POST的隐藏值来保护自己免受恶意值注入。

将所有重要内容存储在服务器端,通过模型将哈希/私钥传递给用户,并实现静态会话字典以存储这些小信息。