Проблема с отображением ViewModel в форме создания - PullRequest
0 голосов
/ 03 мая 2020

Я учусь использовать ViewModel для отображения полей из 2 разных моделей. У меня есть одна модель, содержащая MsgTypeId, MsgType и MsgStatus, а другая модель OptStatus, содержащая StatusId, StatusName и StatusValue. MsgStatus будет отображаться в форме раскрывающегося списка и отображать все значения в OptStatus. Обе модели имеют отдельную таблицу базы данных для хранения своих значений.

namespace theManager.Areas.Settings.Models
{
    public class OptStatus
    {
        [Required]
        [Key]
        public int StatusId { get; set; }

        [Required]
        public string StatusName { get; set; }

        [Required]
        public char StatusValue { get; set; }
    }
}


namespace theManager.Areas.Settings.Models
{
        public class OptMsgType
        {
            [Required]
            [Key]
            public int MsgTypeId { get; set; }
            [Required]
            public string MsgType { get; set; }
            [Required]
            public string MsgStatus { get; set; }     

        }
}

Я создал ViewModel для отображения этих полей в форме Создать OptMsgType. Однако при выполнении кода я получил ошибку

"System.NullReferenceException: 'Ссылка на объект не установлена ​​для экземпляра объекта.'"

I хотел бы спросить, если что-то не так с моей ViewModel. Спасибо!

namespace theManager.Areas.Settings.ViewModels
{
    public class OptMsgTypeCreateViewModel
    {
        public OptMsgType OptMsgType { get; set; }
        public IEnumerable<SelectListItem> OptStatuses { get; set; }
    }
}

OptMsgTypeController.cs

public IActionResult Create(int id)
        {
            var OptMsgTypeViewModel = new OptMsgTypeCreateViewModel();
            OptMsgTypeViewModel.OptStatuses = _context.OptStatus.ToList().Select(x => new SelectListItem
            {
                Text = x.StatusName,
                Value = x.StatusValue.ToString()
            });

            OptMsgTypeViewModel.OptMsgType = _context.OptMsgType.Where(a => a.MsgTypeId == id).FirstOrDefault();
            //var v = _context.OptMsgType.Where(a => a.MsgTypeId == id).FirstOrDefault();
            return View(OptMsgTypeViewModel);

        }

У меня проблемы с отображением формы создания, в которой отображаются поля, объявленные в ViewModel.

@model theManager.Areas.Settings.ViewModels.OptMsgTypeCreateViewModel


@{
    ViewData["Title"] = "Create";
    Layout = null;
}

<h2>Message Type Settings</h2>


@using (Html.BeginForm("Create","OptMsgType", FormMethod.Post, new { id= "popupForm" }))
{
    if (Model != null && Model.OptMsgType.MsgTypeId > 0)
    {
        @Html.HiddenFor(a=>a.OptMsgType.MsgTypeId)
    }

    <div class="form-group">
        <label>Message Type ID</label>
        @Html.TextBoxFor(a=>a.OptMsgType.MsgTypeId,new { @class = "form-control" })
        @Html.ValidationMessageFor(a=>a.OptMsgType.MsgTypeId)
    </div>
    <div class="form-group">
        <label>Leave Type</label>
        @Html.TextBoxFor(a => a.OptMsgType.MsgType, new { @class = "form-control" })
        @Html.ValidationMessageFor(a => a.OptMsgType.MsgType)
    </div>
    <div class="form-group">
        <label>Status</label>
        @Html.DropDownListFor(model => model.OptStatuses, new SelectList(Model.OptStatuses, "Value", "Text"), htmlAttributes: new { @class = "form-control", id = "OptStatus" })
        @Html.ValidationMessageFor(a => a.OptStatuses)
    </div>

    <div>
        <input type="submit" value="Create" />
    </div>
}

Ответы [ 3 ]

0 голосов
/ 03 мая 2020

Привет в действии контроллера, вы должны изменить этот код:

    OptMsgTypeViewModel.OptStatuses = _context.OptStatus.ToList().Select(x => new  SelectListItem
                {
                    Text = x.StatusName,
                    Value = x.StatusValue.ToString()
                });

Я думаю, _context.OptStatus.ToList () в нуль, так что вы получите это исключение. изменить код на это:

OptMsgTypeViewModel.OptStatuses =new list<SelectListItem>();
   var temp= _context.OptStatus.ToList();
if(temp!=null&&temp.count()>0)
{
    OptMsgTypeViewModel.OptStatuses = temp.Select(x => new SelectListItem
                {
                    Text = x.StatusName,
                    Value = x.StatusValue.ToString()
                }).tolist();
}

РЕДАКТИРОВАТЬ: Я думаю, что этот объект "Model.OptMsgType" является нулевым кодом изменения в представлении, как это:

if (Model != null && Model.OptMsgType!=null && Model.OptMsgType.MsgTypeId > 0)
        {
            @Html.HiddenFor(a=>a.OptMsgType.MsgTypeId)
        }
0 голосов
/ 03 мая 2020

@ Джордж, спасибо за ответ. Пожалуйста, попробуйте следующее: создайте экземпляр своего класса в модели представления.

public class OptMsgTypeCreateViewModel
{
   public  OptMsgTypeCreateViewModel()
    {
      OptMsgType = new OptMsgType();
    }
    public OptMsgType OptMsgType { get; set; }
    public IEnumerable<SelectListItem> OptStatuses { get; set; }
}
0 голосов
/ 03 мая 2020

System.NullReferenceException указывает, что вы используете поле без его инициализации. Это может быть проблемой с вашей моделью представления, или это может быть проблемой в другом месте. Например, из кода smaple невозможно увидеть, где вы инициализируете контекст, который используете для получения данных, и это может быть причиной исключения, которое вы получаете.

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

Что касается вашей модели представления, считается хорошей практикой всегда инициализировать списки вашей модели в конструкторе. вашего класса. Таким образом, вы можете гарантировать, что они уже инициализированы, когда вы пытаетесь их использовать.

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

public  OptMsgTypeCreateViewModel()
    {
        OptStatuses  = new List<OptStatus>();
    }
...