Базовая модель ViewModel не указана при обратной передаче создания действия с MVC3 - PullRequest
1 голос
/ 24 января 2012

У меня возникли проблемы с тем, чтобы моя ViewModel возвратила ненулевой объект в свойстве базовой модели в обратной передаче действия Create моего контроллера.В настоящее время у меня есть другая страница, которая выполняет те же самые операции с другой моделью, которая имеет почти те же свойства, и эта форма работает отлично, поэтому я чувствую, что упускаю что-то простое, хотя не могу определить, что не так.

Вот моя ViewModel с моим Базовым классом:

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 имеет форму, связанную с этим вопросомЯ спрашивал ранее.

Редактировать:

Я проверил ошибку ModelState и получаю исключение

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

Я также удалил логику, которая добавляет типы Failureи я все еще получаю ту же проблему.Таким образом, похоже, что проблема связана с сопоставлением Viewmodel.action.Description с действием.

1 Ответ

2 голосов
/ 26 января 2012

Проблема заключается в следующем свойстве SystemFailureActionViewModel:

public SystemFailureAction action { get; set; }

В ASP.NET MVC action и controller являются своего рода зарезервированными словами.Они являются частью каждого маршрута.И если у вас есть свойство, названное таким образом, оно конфликтует со строковым значением, которое указывает на имя действия и которое, очевидно, не может быть связано со сложным SystemFailureAction типом.

Так что, чтобы решить проблему, просто переименуйте этоНедвижимость на ваш взгляд модель:

public SystemFailureAction FailureAction { get; set; }
...