MVC错误:传递到字典中的模型项为空。

13

我只是试图创建一个视图,但我遇到了以下错误:

System.InvalidOperationException:传递给字典的模型项为空,但此字典需要类型为 'System.DateTime' 的非空模型项。

现在,我知道为什么会出现这个错误,数据库中的特定字段确实为空,但是这是预期的,因为它是稍后编辑的内容。这是我的代码:

操作

public ActionResult View(Int64? Id)
    {

        ModelContainer ctn = new ModelContainer();
        var item = from t in ctn.Items where t.ItemID == Id select t;
        return View(Item.First());
    }

主视图

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Administrator.Master" Inherits="System.Web.Mvc.ViewPage<myApp.Data.Item>" %>

<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
    View
</asp:Content>

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">

    <% Html.RenderPartial("Details", Model); %>

</asp:Content>

<asp:Content ID="Content3" ContentPlaceHolderID="Header" runat="server">
<h1>Details - <%= Model.MainItem %></h1>
</asp:Content>

局部视图

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<myApp.Data.Item>" %>
<%@ Import Namespace="myApp.Supplier.Web.Extensions" %>

    <fieldset>

        <legend>Information</legend>

        <div class="fieldset">

            <%= Html.LabelFor(m => m.MainItem)%>
            <%= Html.DisplayFor(m => m.MainItem, "FormTextShort")%><br />
            <%= Html.LabelFor(m => m.Supplier.Name)%>
            <%= Html.DisplayFor(m => m.Supplier.Name, "FormTextShort")%><br />
            <%= Html.LabelFor(m => m.ProductCode)%>
            <%= Html.DisplayFor(m => m.ProductCode, "FormTextShort")%><br />
            <%= Html.LabelFor(m => m.Product.SubmissionDate)%>
            <%= Html.DisplayFor(m => m.Product.SubmissionDate, "FormDateShort")%><br />
            <%= Html.LabelFor(m => m.Product.SentForRepair)%>
            <%= Html.DisplayFor(m => m.Product.SentForRepair, "FormDateShort")%><br />
         </div>

    </fieldset>

在这种情况下,x.Product.SentForRepair日期为空,因为在提交时它尚未被发送。我有其他类似的字段,例如totalCost等,但是为了简单起见,我没有在此处包含它们。如果我注释掉SentForRepair行,视图将完美地显示其他信息。如果有人能指点我如何解决这个错误,我会非常感激! :)
4个回答

16

在显示模板中,您需要检查空值(在将其强类型转换为DateTime?后):

<% if (Model.HasValue) { %>
    <%= Html.Encode(Model.Value.ToString("yyyy-MM-dd")) %>
<% } %>

或者,如果您想要提供一个自定义日期格式,您可以删除FormDateShort显示模板,并使用[DisplayFormat]属性装饰您的视图模型属性:

[DisplayFormat(NullDisplayText = "", DataFormatString = "{0:yyyy-MM-dd}")]
public DateTime? SentForRepair { get; set; }

然后简单地执行:

<%= Html.DisplayFor(m => m.Product.SentForRepair)%>

嗨Darin,再次感谢您的好回复 :) 只是一个快速的问题,根据这个视图,我打算允许用户点击一个编辑按钮,带他/她进入一个视图,在那里他可以输入缺失的数据。您认为当我尝试显示EditorFor文本框时,我会在那个视图中遇到相同的问题吗? - 109221793
另外,再提供一些信息,该模型直接来自数据库,而不是视图模型,因此我不确定如何实现上面的[DisplayFormat()]属性。 - 109221793
@109221793,关于你的第一个问题,我不太明白你在问什么。至于第二个问题,无论你的模型来自哪里,你都应该始终使用视图模型。 - Darin Dimitrov
我会考虑关于ViewModels的建议。我的第一个评论是指,在我原来的问题中所跟踪的页面后面,我计划显示一个编辑页面,用户可以在其中编辑详细信息。在这个视图中,我将不得不显示空字段。我应该期望相同的错误吗? - 109221793
@109221793,如果您在显示模板中检查 null 值,就不应该有任何问题。 - Darin Dimitrov

11

6

将自定义编辑器模板中的类型从 DateTime 更改为可空的 datetime 类型(DateTime?)

@model System.DateTime?

@Html.TextBox("", ViewData.TemplateInfo.FormattedModelValue,
                      new { @class = "text-box single-line", data_datepicker="true"})

1
只需更改您的FormDateShort模板,使其接受DateTime?而不是DateTime,并放置一些逻辑来检查在呈现之前是否有值。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接