Значения формы ASP.NET MVC не устанавливаются при публикации - PullRequest
2 голосов
/ 02 сентября 2010

У меня есть объект модели под названием Проблема:

[Table(Name = "Problems")]
public class Problem
{
    [HiddenInput(DisplayValue = false)]
    [Column(IsPrimaryKey = true, IsDbGenerated = true, AutoSync = AutoSync.OnInsert)]
    public int ProblemId { get; set; }

    [Display(ResourceType = typeof(Resources.Resources), Name = "TablePersonStudentName")]
    [Column] public int StudentId { get; set; }

    [Display(ResourceType = typeof(Resources.Resources), Name = "TableCommunicationTypesName")]
    [Column] public int CommunicationTypeId { get; set; }

    [Display(ResourceType = typeof(Resources.Resources), Name = "TableProblemTypeName")]
    [Column] public int ProblemTypeId { get; set; }

    [Display(ResourceType = typeof(Resources.Resources), Name = "TableMitigatingCircumstanceLevelName")]
    [Column] public int MitigatingCircumstanceLevelId { get; set; }

    [Display(ResourceType = typeof(Resources.Resources), Name = "TableProblemDate")]
    [Column] public DateTime? DateTime { get; set; }

    [Display(ResourceType = typeof(Resources.Resources), Name = "TableProblemOutline")]
    [Column] public string Outline { get; set; }

    [Display(ResourceType = typeof(Resources.Resources), Name = "TableProblemFile")]
    [Column] public byte[] MitigatingCircumstanceFile { get; set; }

    [Display(ResourceType = typeof(Resources.Resources), Name = "TableProblemAbsentFrom")]
    [Column] public DateTime? AbsentFrom { get; set; }

    [Display(ResourceType = typeof(Resources.Resources), Name = "TableProblemAbsentUntil")]
    [Column] public DateTime? AbsentUntil { get; set; }

    [Display(ResourceType = typeof(Resources.Resources), Name = "TableProblemRequestedFollowUp")]
    [Column] public DateTime? RequestedFollowUp { get; set; }

    public CommunicationType CommunicationType { get; set; }

    public MitigatingCircumstanceLevel MitigatingCircumstanceLevel { get; set; }

    public ProblemType ProblemCategory { get; set; }

    public ICollection<ProblemCommunication> ProblemCommunications { get; set; }

    public ICollection<AssessmentExtension> AssessmentExtensions { get; set; }

    public ICollection<User> Users { get; set; }

}

Поскольку эта модель содержит множество объектов из других таблиц базы данных, я использую раскрывающиеся списки в своем представлении с использованием viewModel:

public class ProblemViewModel
{
    public Problem Problem { get; set; }
    public SelectList Students { get; set; }
    public SelectList CommunicationType { get; set; }
    public SelectList MitigatingCircumstanceLevel { get; set; }
    public SelectList ProblemType { get; set; }
    public MultiSelectList ProblemUsers { get; set; }

    public ProblemViewModel(Problem problem, ISqlStudentRepository sqlStudentRepository, 
        ISqlCommunicationTypeRepository sqlCommunicationTypeRepository, ISqlMitigatingCircumstanceLevelRepository sqlMitigatingCircumstanceRepository,
        ISqlProblemTypeRepository sqlProblemTypeRepository, ISqlUserRepository sqlUserRepository,
        string username)
    {
        this.Problem = problem;
        this.Students = new SelectList(sqlStudentRepository.Students.ToList(), "StudentId", "FirstName");
        this.CommunicationType = new SelectList(sqlCommunicationTypeRepository.CommunicationTypes.ToList(), "CommunicationTypeId", "Name");
        this.MitigatingCircumstanceLevel = new SelectList(sqlMitigatingCircumstanceRepository.MitigatingCircumstanceLevels.ToList(), "MitigatingCircumstanceLevelId", "Name");
        this.ProblemType = new SelectList(sqlProblemTypeRepository.ProblemTypes.ToList(), "ProblemTypeId", "TypeName");
        this.ProblemUsers = new MultiSelectList(sqlUserRepository.Users.Where(s => s.UserName != username).ToList(), "UserId", "UserName");
    }
}

Это генерируется при переходе к методу «Задача / Создать контроллер»:

public ViewResult Create()
    {
        string username = User.Identity.Name;

        return View("Edit", new ProblemViewModel(new Problem(), sqlStudentRepository, 
            sqlCommunicationTypeRepository, sqlMitigatingCircumstanceRepository,
            sqlProblemTypeRepository, sqlUserRepository, username));
    }

Вот представление ascx:

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<BournemouthUniversity.WebUI.Models.ProblemViewModel>" %>
        <div class="editor-field">
            <%: Html.HiddenFor(model => model.Problem.ProblemId)%>
            <%: Html.ValidationMessageFor(model => model.Problem.ProblemId)%>
        </div>

        <div class="editor-label">
            <%: Html.LabelFor(model => model.Problem.StudentId) %>
        </div>
        <div class="editor-field">
            <%: Html.DropDownListFor(model => model.Problem.StudentId, Model.Students)%>
            <%: Html.ValidationMessageFor(model => model.Problem.StudentId)%>
        </div>

        <div class="editor-label">
            <%: Html.LabelFor(model => model.Problem.CommunicationTypeId)%>
        </div>
        <div class="editor-field">
            <%: Html.DropDownListFor(model => model.Problem.CommunicationTypeId, Model.CommunicationType)%>
            <%: Html.ValidationMessageFor(model => model.Problem.CommunicationTypeId)%>
        </div>

        <div class="editor-label">
            <%: Html.LabelFor(model => model.Problem.ProblemTypeId)%>
        </div>
        <div class="editor-field">
            <%: Html.DropDownListFor(model => model.Problem.ProblemTypeId, Model.ProblemType)%>
            <%: Html.ValidationMessageFor(model => model.Problem.ProblemTypeId)%>
        </div>

        <div class="editor-label">
            <%: Html.LabelFor(model => model.Problem.MitigatingCircumstanceLevelId)%>
        </div>
        <div class="editor-field">
            <%: Html.DropDownListFor(model => model.Problem.MitigatingCircumstanceLevelId, Model.MitigatingCircumstanceLevel)%>
            <%: Html.ValidationMessageFor(model => model.Problem.MitigatingCircumstanceLevelId)%>
        </div>

        <div class="editor-label">
            <%: Html.LabelFor(model => model.Problem.DateTime)%>
        </div>
        <div class="editor-field">
            <%: Html.TextBoxFor(model => model.Problem.DateTime, new { @class = "datePicker" })%>
            <%: Html.ValidationMessageFor(model => model.Problem.DateTime)%>
        </div>

        <div class="editor-label">
            <%: Html.LabelFor(model => model.Problem.Outline)%>
        </div>
        <div class="editor-field">
            <%: Html.TextAreaFor(model => model.Problem.Outline, 6, 70, new { maxlength = 255 })%>
            <%: Html.ValidationMessageFor(model => model.Problem.Outline)%>
        </div>

        <div class="editor-label">
            <%: Html.LabelFor(model => model.Problem.AbsentFrom)%>
        </div>
        <div class="editor-field">
            <%: Html.TextBoxFor(model => model.Problem.AbsentFrom, new { @class = "datePicker" })%>
            <%: Html.ValidationMessageFor(model => model.Problem.AbsentFrom)%>
        </div>

        <div class="editor-label">
            <%: Html.LabelFor(model => model.Problem.AbsentUntil)%>
        </div>
        <div class="editor-field">
            <%: Html.TextBoxFor(model => model.Problem.AbsentUntil, new { @class = "datePicker" })%>
            <%: Html.ValidationMessageFor(model => model.Problem.AbsentUntil)%>
        </div>

        <div class="editor-label">
            <%: Html.LabelFor(model => model.Problem.RequestedFollowUp)%>
        </div>
        <div class="editor-field">
            <%: Html.TextBoxFor(model => model.Problem.RequestedFollowUp, new { @class = "dateTimePicker" })%>
            <%: Html.ValidationMessageFor(model => model.Problem.RequestedFollowUp)%>
        </div>

        <div class="editor-label">
            <%: Html.LabelFor(model => model.Problem.Users)%>
        </div>
        <div class="editor-field">
            <%: Html.ListBoxFor(model => model.Problem.Users, Model.ProblemUsers, new { @class = "multiselect" })%>
            <%: Html.ValidationMessageFor(model => model.Problem.Users)%>
        </div>

        <p>
            <input type="submit" class="button" value="Save" />
        </p>

<% } %>

Однако, когда я отправляю форму, вводится действие контроллера редактирования [HttpPost], но с нулевым значением для большинства значений ...

[HttpPost]
    public ActionResult Edit(Problem problemValues)
    {
        try
        {
            MembershipUser myObject = Membership.GetUser();
            String UserId = myObject.ProviderUserKey.ToString();

            Problem problem = problemValues.ProblemId == 0
                ? new Problem()
                : sqlProblemRepository.Problems(UserId).First(p => p.ProblemId == problemValues.ProblemId);
            TryUpdateModel(problem);

            if (ModelState.IsValid)
            {
                sqlProblemRepository.SaveProblem(problem);
                TempData["message"] = problem.ProblemId + " has been saved.";

                if (Request.IsAjaxRequest())
                {
                    return Json(problem);
                }

                return RedirectToAction("Details", "Student", new { problem.StudentId });
            }
            else
                return View(problem);
        }
        catch (Exception ex)
        {
            if (Request.IsAjaxRequest())
            {
                return Json(null);
            }
            else
            {
                TempData["message"] = "Record Not Found.";
                return RedirectToAction("Index");
            }
        }
    }

alt text

Любые идеи по этому поводу были бы оценены, так как это происходит в большинстве моих форм, где у меня есть выпадающие списки, однако я не понимаю, почему все значения равны нулю, даже не выпадающие поля.

Заранее спасибо ...

Jonathan

Ответы [ 3 ]

2 голосов
/ 02 сентября 2010

Я бы порекомендовал вам хранить ваши репозитории отдельно от модели.Таким образом, все, что вы передаете в представление, это модель.Ни View, ни ViewModel не должны нуждаться в каком-либо репозитории.Как это работает, контроллер использует хранилище для извлечения модели и передачи этой модели в представление:

public ViewResult Create()
{
    string username = User.Identity.Name;
    Problem model = someRepository.FetchModel(username);
    ProblemViewModel viewModel = someMapper.ConvertToViewModel(model);

    return View("Edit", viewModel);
}

И действие отправки:

[HttpPost]
public ViewResult Create(ProblemViewModel viewModel)
{
    // viewModel will contain all the fields that you have corresponding
    // inputs in the View
    ...
}
1 голос
/ 02 сентября 2010

если вы проверите HTML, сгенерированный, я думаю, вы обнаружите, что поля формы используют точечную нотацию ... в основном отправка обратной модели. Проблема вместо просто проблемы ... В этом и заключается ваша ... э-э ... проблема

редактировать Я не проделал большую работу, объясняя это, я думаю .... Ваши html-поля должны публиковать обратные свойства, которые будут сопоставлены с моделью, принятой действием, в этом случае действие ожидает модель проблемы .... однако ваши HTML-поля публикуют модель, в которой есть проблема ..., а не проблема.

0 голосов
/ 02 сентября 2010

Я думаю, вам нужно изменить подпись вашего действия Edit на

[HttpPost]
public ActionResult Edit(int problemId, Problem problemValues)
{
.
.
}

, похоже, у вас та же проблема, что и здесь: MVC Custom ViewModel и автоматическое связывание

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...