使用MVC3创建操作回发时,ViewModel基本模型为null

时间:2012-01-24 14:48:57

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

我在使用我的ViewModel在控制器的Create action postback中的基本模型属性中返回非null对象时遇到了一些麻烦。我目前有另一个页面在另一个具有几乎相同属性的模型上执行完全相同的操作,并且该表单工作正常,所以我觉得我缺少一些基本的东西,尽管我不能放错了。< / p>

这是我的ViewModel和我的Base类:

public class SystemFailureActionViewModel
{
    /// <summary>
    /// View model class for adding and modifying SystemFailureActions
    /// </summary>
    public SystemFailureAction action { get; set; }

    //properties
    public int TypeID { get; set; }
    public string TypeDescription { get; set; }
    public bool Assigned { get; set; } 

    public SystemFailureActionViewModel() { }

    public SystemFailureActionViewModel(SystemFailureAction action)
    {
        this.action = action;
    }

    //Collections for views
    public IEnumerable<SelectListItem> EditSystemFailiureTypesList { get { return ModelListProvider.FilteredSystemFailureTypeList; } }
    public IEnumerable<SelectListItem> DetailsSystemFailiureTypesList { get { return ModelListProvider.FullSystemFailureTypeList; } }
}

[MetadataType(typeof(SystemFailureActionMetadata))]
public partial class SystemFailureAction
{
    private class SystemFailureActionMetadata
    {
        /// <summary>
        /// ID for this failure action
        /// </summary>
        public int ID { get; set; }

        /// <summary>
        /// Action Description
        /// </summary>
        [Required]
        [StringLength(200)]
        [DisplayName("Action Description")]
        public string Description { get; set; }
    }
}

这是我的Controller Add和Add Postback方法:

public ActionResult Add()
    {
        SystemFailureAction action = new SystemFailureAction();
        action.Description = "";
        populateSystemFailureActionData(action);
        return PartialView("Form", new SystemFailureActionViewModel(action));
    }


    [HttpPost]
    public ActionResult Add(SystemFailureActionViewModel viewModel, string[] selectedTypes, FormCollection collection)
    {
        SystemFailureAction newAction = viewModel.action;

        if (!ModelState.IsValid)
        {
            populateSystemFailureActionData(newAction);
            return PartialView("Form", new SystemFailureActionViewModel(newAction));
        }

        try
        {
            //Insert the new failure action type 
            context.SystemFailureActions.InsertOnSubmit(newAction);
            context.SubmitChanges();

            //Insert the failure type mappings
            updateSystemFailureAssociationData(newAction, selectedTypes);
            context.SubmitChanges();

            //Return the new data
            populateSystemFailureActionData(newAction);
            return PartialView("Done", new SystemFailureActionViewModel(newAction));
        }
        catch (Exception ex)
        {
            ModelState.AddModelError("", ex.Message);
            populateSystemFailureActionData(newAction);
            return PartialView("Form", new SystemFailureActionViewModel(newAction));
        }           
    }      

最后这是我的表单,它被加载到Jquery对话框中,并且回发是通过Ajax完成的。

  @using (Ajax.BeginForm(new AjaxOptions
{
    HttpMethod = "Post",
    UpdateTargetId = "formDialog",
    InsertionMode = InsertionMode.Replace,
    OnSuccess = "onDialogDone()"
}))
{
    @Html.ValidationSummary(true)
    <div>
        <div class="editor-label">
            @Html.LabelFor(model => model.action.Description)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.action.Description)
        </div>
    </div>
    <div class="categoryFieldSet">
        <fieldset>
            <legend>Mechanical System Failure Categories</legend>
            <div class="editor-field">
                <table>
                    <tr>
                        @{
                            int count = 0;
                            List<ManageMAT.ViewModels.SystemFailureActionViewModel> types = ViewBag.Types;

                            foreach (var type in types)
                            {
                                if (count++ % 3 == 0)
                                {
                                    @: </tr> <tr>
                                }
                                @: <td>
                                    <input type="checkbox"
                                           id="selectedTypes + @type.TypeID"
                                           name="selectedTypes"
                                           value="@type.TypeID"
                                           @(Html.Raw(type.Assigned ? "checked=\"checked\"" : "")) />
                                    <label for="selectedTypes + @type.TypeID">@type.TypeDescription</label>
                                @:</td>
                            }
                        @:</tr>
                        }
                </table>
            </div>
        </fieldset>
    </div>
}

如果您想知道ViewBag.Types逻辑在表单中的含义,那么它与我前面提到的this问题有关。

编辑:

我检查了ModelState错误,我得到的异常是

"The parameter conversion from type 'System.String' to type Models.SystemFailureAction' failed because no type converter can convert between these types."

我还删除了添加失败类型的逻辑,我仍然收到同样的问题。因此,问题似乎来自将Viewmodel.action.Description映射到操作。

1 个答案:

答案 0 :(得分:2)

问题是SystemFailureActionViewModel上的以下属性:

public SystemFailureAction action { get; set; }

在ASP.NET MVC actioncontroller中有点保留字。它们是每条路线的一部分。如果您有一个以这种方式调用的属性,它会与指向操作名称的字符串值冲突,并且显然不能绑定到复杂的SystemFailureAction类型。

因此,要解决此问题,只需在视图模型上重命名此属性:

public SystemFailureAction FailureAction { get; set; }