2012-01-13 39 views
0

我创建了以下视图供用户创建新项目。我试图创建一些验证,所以如果用户将字段留空,那么它会生成验证消息。但是,如果用户确实将字段留空,则我的应用程序会在Model.Designer.cs文件中的以下行上崩溃:_headline = structuralObject.SetValidValue(value, false)。因为:由于验证导致应用程序崩溃 - '此属性不能设置为空值'

此属性不能设置为空值。我Model.Designer.cs文件

部分:

[EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=false)] 
    [DataMemberAttribute()] 
    public global::System.String headline 
    { 
     get 
     { 
      return _headline; 
     } 
     set 
     { 
      OnheadlineChanging(value); 
      ReportPropertyChanging("headline"); 
     _headline = StructuralObject.SetValidValue(value, false); 
      ReportPropertyChanged("headline"); 
      OnheadlineChanged(); 
     } 
    } 

的代码段适用于作为我创建视图如下:

@using (Html.BeginForm()) { 
@Html.ValidationSummary(true) 

<fieldset> 

    <legend>News Details</legend> 

    <br /> 
     Posted Date: 
      <div class="editor-field"> 
       @Html.EditorFor(model => model.posted) 
       @Html.ValidationMessageFor(model => model.posted) 
      </div> 

    <br /> 

     Headline Title: 
      <div class="editor-field"> 
       @Html.EditorFor(model => model.headline) 
       @Html.ValidationMessageFor(model => model.headline) 
      </div> 

    <br /> 

的以下是我的AccountModels.cs文件,其中我输入了对视图的验证:

[MetadataType(typeof(NewsValidation))] 

public partial class News 
{ 
} 

public class NewsValidation 
{ 

    [Required(ErrorMessage = "Posted date is required")] 
    public DateTime posted { get; set; } 

    [Required(ErrorMessage = "Headline is required")] 
    [Display(Name = "Headline")] 
    public string headline { get; set; } 

    [Required(ErrorMessage = "Story body is required")] 
    public string story { get; set; } 
} 

我被告知这是因为我的数据库允许空值,但是自那时以来,我创建了一个不再允许空值的新数据库。我的应用程序仍然崩溃,不知道从哪里开始。这是奇怪的事情,当它崩溃时,我点击播放继续播放,并出现验证。所以它看起来像验证工作,但由于某种原因应用程序事先崩溃。

任何人都可以提供任何支持?

+0

我对MVC了解不多,但是......不应该让'IsNullable = false'部分引发这个问题吗? – PedroC88 2012-01-13 22:11:33

+0

然后我会尝试自动生成Model.Designer.cs文件。谢谢你看:-) – Blob 2012-01-13 22:13:31

回答

0

问题是您的域模型上的headline属性的setter尝试执行更新。当它尝试绑定来自请求的动作参数时,默认模型绑定器将调用此setter。如果用户将标题栏留空,您将会得到这个例外。

我会非常强烈地推荐你使用视图模型,并且绝不会将你的领域模型传递给视图。所以定义一个简单的NewsViewModel:

public class NewsViewModel 
{ 
    public DateTime Posted { get; set; } 

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

,然后让你的控制器动作把它传递给视图:

public class HeadlinesController: Controller 
{ 
    public ActionResult Index() 
    { 
     var model = new NewsViewModel(); 
     return View(model); 
    } 

    [HttpPost] 
    public ActionResult Index(NewsViewModel model) 
    { 
     if (!ModelState.IsValid) 
     { 
      // there were validation errors. For example the user 
      // left the headline field blank => redisplay the view 
      return View(model); 
     } 

     // at this stage we know that validation passed => we can 
     // process our domain model. 
     var news = new News(); 
     news.posted = model.Posted; 
     news.headline = model.Headline; 

     return RedirectToAction("success"); 
    } 
} 

,显然认为将有力地现在输入到您的视图模型:

@model NewsViewModel 
@using (Html.BeginForm()) 
{ 
    @Html.ValidationSummary(true) 
    <fieldset> 
     <legend>News Details</legend> 

     <br /> 
     Posted Date: 
     <div class="editor-field"> 
      @Html.EditorFor(model => model.Posted) 
      @Html.ValidationMessageFor(model => model.Posted) 
     </div> 

     <br /> 

     Headline Title: 
     <div class="editor-field"> 
      @Html.EditorFor(model => model.Headline) 
      @Html.ValidationMessageFor(model => model.Headline) 
     </div> 

     <br /> 

     <button type="submit">OK</submit> 
    </fieldset> 
} 
+0

我目前的“创建”视图与你的看起来不一样,上述情况是否仍然适用? [HttpPost,ValidateInput(假)] 公共的ActionResult创建(新闻新闻) { 如果(ModelState.IsValid) { 变种latestStory = _db.News.OrderByDescending(N => n.storyId).FirstOrDefault(); var nextStoryId = latestStory.storyId + 1; news.storyId = nextStoryId; _db.News.AddObject(news); _db.SaveChanges(); TempData [“StoryCreated”] =“新故事创建成功”; return RedirectToAction(“UniversityHomepage”); } return查看(news); } – Blob 2012-01-14 10:15:35

+0

@ user1091114,不,不要使用News作为控制器操作的参数。那就是问题所在。默认的模型绑定器调用setter。并且setter按照你实现它的方式崩溃(实际上不是你,而是在自动生成的文件中)。你应该像我在我的答案中解释的那样定义一个NewsViewModel并使用这个视图模型。 – 2012-01-14 10:16:48

+0

当我运行我的应用程序时,我在我的IE窗口中收到以下内容:'传入字典的模型项目类型为'File.Models.NewsViewModel',但此字典需要一个'File.Models.News' 。 描述:执行当前Web请求期间发生未处理的异常。请查看堆栈跟踪以获取有关该错误的更多信息以及源代码的来源。 是因为我在做:Return View(model);而不仅仅是返回视图()? – Blob 2012-01-14 10:42:41

0

如果应用程序崩溃,但您可以点击play并且它高兴地继续并执行验证,那么您的调试是否设置为显示所有抛出的异常,而不仅仅是用户未处理的异常?也许StructuralObject.SetValidValue()正在使用流量控制的异常。

  1. 进入调试>例外
  2. 如果你没有一个“用户未处理”一栏中,点击工具>选项>调试>常规,然后选中启用仅我的代码(仅限托管)
  3. 在调试>例外,取消“时抛出”并选中“用户未处理”下公共语言运行库异常

只是一种预感 - 这有什么区别?

+0

嗨史蒂夫, 我认为这是我的代码的问题,因为它只是没有选择验证之前处理。我检查了我的设置:用户异常:C++异常,公共语言运行时异常,托管调试助手,本机运行时检查和Win32异常都在'User-unhandled'下有勾号。非勾选'投掷'。 '启用只是我的代码(只管理)'也被勾选。 谢谢你的回复:-) – Blob 2012-01-13 23:12:32

相关问题