首页 > 解决方案 > 混合了我的两个模型,发布请求中的空引用(ASP.NET MVC)

问题描述

我正在尝试提供一个包含数据库行列表的表,以及一个小表单选项,供用户添加额外的数据库行。我制作了两个模型来保存表格行并捕获表格。我对表格模型没有问题,只是表格模型。

所以我相信问题出在我的控制器上;我是 MVC 的新手,这是我第一次在同一个 VM 中看到两个模型……我一直在反复对事物进行一些小的更改,但我的控制器中不断出现空引用错误。

虚拟机:

namespace User.ViewModel
{
    public class UploadDocumentTemplatesViewModel
    {
        public string TemplateName { get; set; }
        public string Comments { get; set; }
    }

    public class TemplateModel
    {
        public UploadDocumentTemplatesViewModel NewTemplate { get; set; }
        public List<UploadDocumentTemplatesViewModel> Templates { get; set; }
    }
}

查看(UploadDocumentTemplates.cshtml):

@using (Html.BeginForm("AddNewTemplate", "User", FormMethod.Post, new { enctype = "multipart/form-data", id = "NewTemplateForm"}))
{
     @Html.AntiForgeryToken()
     <div>
          <input type="text" class="form-control" rows="5" id="TemplateName" value="@Model.NewTemplate.TemplateName">
          <label for="comments">Comments:</label>
          <textarea class="form-control" rows="5" id="comments" name="@Model.NewTemplate.Comments"></textarea>
          <button id="AddTemplate" onclick="AddNewTemplate()" name="Add Template">Add Template</button>
    </div>
}

<table>
    <tbody>
    @{ foreach (var template in Model.Templates)
    {
         <tr id="tr_@template.DocumentTemplateId">
         <td>@template.TemplateName</td>
         <td>@template.Comments </td>
         <td>@template.IsActive </td>
    }

<script>
function AddNewTemplate() {
            $("#NewTemplateForm").submit();
}
</script>

控制器:

public class UserController : Controller
    {
public ActionResult UploadDocumentTemplates()
        {
            var model = entity.DocumentTemplates.Select(x => new UploadDocumentTemplatesViewModel()
            {
                DocumentTemplateId = x.DocumentTemplateId,
                TemplateName = x.TemplateName,
                Comments = x.Comments,
            });
    
            var _obj = new TemplateModel();

            var templatelist = _entities.GetTemplates();
            _obj.Templates = new List<UploadDocumentTemplatesViewModel>();

            foreach (var template in templatelist)
            {
                _obj.Templates.Add(new UploadDocumentTemplatesViewModel()
                {
                    TemplateName = template.TemplateName,
                    Comments = template.Comments,
                });
            }

            _obj.NewTemplate = new UploadDocumentTemplatesViewModel();
    

            return View(_obj);
        }



        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult AddNewTemplate(TemplateModel vModel)
        {
            var template = new DocumentTemplates();


            template.TemplateName = vModel.NewTemplate.TemplateName;
            template.Comments = vModel.NewTemplate.Comments;
    
            entity.DocumentTemplates.Add(template);
            entity.SaveChanges();


            return View("~/User/UploadDocumentTemplates.cshtml", vModel);
        }
}

我在控制器的 Post 方法中在这一行点击了空引用:

template.TemplateName = vModel.NewTemplate.TemplateName;

vModel.NewTemplate.TemplateName 为空。谁能帮我这个?

太感谢了!

解决方案:

在安迪的帮助下,NRE 确实得到了解决(见答案)。在我使用表单中使用的字段填充新 VM 后,我的进一步问题得到了解决。

namespace Example.Areas.ViewModel
{
    public class UploadDocumentTemplatesViewModel
    {
        public long DocumentTemplateId { get; set; }
        public string TemplateName { get; set; }
        public string Comments { get; set; }

    }

    public class TemplateModel
    {
        public string TemplateName { get; set; }
        public string Comments { get; set; }
        public HttpPostedFileBase TemplateFile { get; set; }

        public List<UploadDocumentTemplatesViewModel> Templates { get; set; }
    }
}

在控制器中,我填充了 TemplateModel 并将其发送到视图:

public ActionResult UploadDocumentTemplates()
        {

            var templateList = Repository.GetTemplates();

            var _obj = new TemplateModel
            {
                Templates = templateList.Select(x => new UploadDocumentTemplatesViewModel()
                {
                    DocumentTemplateId = x.DocumentTemplateId,
                    TemplateName = x.TemplateName,
                    Comments = x.Comments
                }).ToList()
            };

            return View(_obj);
        }

然后我将@using Example.Areas.ViewModel.TemplateModel 放在我的视图上,并在表格中使用了 Model.Templates,在表单中使用了 Model.TemplateName 和 Model.Comments。

标签: c#asp.net-coreasp.net-mvc-3model-view-controllerasp.net-core-3.1

解决方案


在您点击空引用的行中添加一个断点并检查是否vModel.NewTemplate有一个有效的实例。

您可以在类中添加一个构造函数TemplateModel来创建一个新的实例UploadDocumentTemplatesViewModel()

namespace User.ViewModel
{
    public class UploadDocumentTemplatesViewModel
    {
        public string TemplateName { get; set; }
        public string Comments { get; set; }
    }

    public class TemplateModel
    {
        public TemplateModel()
        {
            NewTemplate = new UploadDocumentTemplatesViewModel();
        }

        public UploadDocumentTemplatesViewModel NewTemplate { get; set; }
        public List<UploadDocumentTemplatesViewModel> Templates { get; set; }
    }
}

或者

实例化后创建一个实例template

var template = new DocumentTemplates();
template.NewTemplate = new UploadDocumentTemplatesViewModel();

推荐阅读