【问题标题】:C# MVC 3 Validation Failing on Particular ViewsC# MVC 3 验证在特定视图上失败
【发布时间】:2012-05-30 10:29:00
【问题描述】:

这是我在这里发布的第一个问题,如果有任何遗漏,请原谅我。我会根据要求更新任何信息。

说明

我正在开发我的第一个 C#.Net MVC-3 应用程序。我正在使用 Entity Framework 4.0 和 Razor 视图引擎。

对于大多数视图,我使用包含部分类实例的视图模型。该部分类派生自 EF 类,并包含这些类成员的数据注释。这很顺利,现在我所有使用该视图模型的视图都对受影响的文本框进行了验证。例子:

部分类:

[MetadataType(typeof(DataPackageMetaData))]
public partial class DataPackage
{
    //empty
}

public class DataPackageMetaData
{
    [Required]
    [StringLength(50)]
    public string DataPackageID { get; set; }

    ... (a lot more stuff like this) ...
}

视图模型:

public class PackageInfo
{
    // Registration Package information
    public DataPackage package { get; set; }
    public Reviewer reviewer { get; set; }
    public PackageTracking trackingSave { get; set; }

    <...>

    //Constructor
    public PackageInfo()
    {
        package = new DataPackage();
        reviewer = new Reviewer();
        trackingSave = new PackageTracking();
    }
}

因此,所有用于该内容的验证内容“都可以正常工作”。在视图(实际上是局部视图的一部分)中,我只放了一个“TextBoxFor”。然后如果验证失败,则会以红色发布一条漂亮的错误消息:

查看:

@Html.TextBoxFor(model => Model.package.DataPackageID, new { @class = "short", @id = "DataPackageID" })
@Html.ValidationMessageFor(model => Model.package.DataPackageID, "The Data Package ID is required and cannot be longer than 50 characters")

问题

我现在遇到的问题是我已经转移到程序的报告方面,我想要一个可以传递“DateIn”和“DateOut”表单值(以及其他内容)的新 ViewModel,以便自定义报告可以生成查询。我希望能够验证 DateIn 和 DateOut 值确实是日期值。出于某种原因,这不起作用。

视图模型:

public class PackageVals
{
    < ... >

    // Date value for formatted "Date In" value
    [DataType(DataType.Date)]
    [DisplayName("Date In")]
    [DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}", ApplyFormatInEditMode = true)]
    [Required]
    public DateTime DateIn { get; set; }

    // Date value for formatted "Date Out" value
    [DataType(DataType.Date)]
    [DisplayName("Date Out")]
    [DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}", ApplyFormatInEditMode = true)]
    [Required]
    public DateTime DateOut { get; set; }

    <... more stuff ...>
}

查看

@Html.TextBoxFor(model => Model.DateIn, new { @class = "small", @id = "DateIn"})
@Html.ValidationMessageFor(model => Model.DateIn, "A valid date must be entered in the format mm/dd/yyyy.")
<...>
@Html.TextBoxFor(model => Model.DateOut, new { @class = "small", @id = "DateOut"})
@Html.ValidationMessageFor(model => Model.DateOut, , "A valid date must be entered in the format mm/dd/yyyy.")

请注意,在所有情况下,我都使用部分视图,然后嵌入到其他视图中。应用程序的报告生成部分有几个不同的视图,几乎所有视图都需要“DateIn”和“DateOut”表单值。

我没有东西可以看,也没有时间看它们了。现在,我只是在 Controller 中错误捕获错误的日期值并传回一个 null ViewModel 以防止用户看到黄色死亡画面。

我知道验证是基于 jQuery 的,但我认为我在那里没有做任何可能导致问题的事情。这是我的整个 jQuery 脚本:

jQuery 脚本

$(document).ready(function () {
    // Purple box autocomplete Stuff
    $("#Product").autocomplete({ source: '/SharedFunctions/AutoFillProduct' });
    $("#ActiveIngredient").autocomplete({ source: '/SharedFunctions/AutoFillActiveIngredient' });
    $("#Applicant").autocomplete({ source: '/SharedFunctions/AutoFillApplicant' });

    // Purple box autocomplete Stuff
    $("#DataType").autocomplete({ source: '/SharedFunctions/AutoFillDataType' });

    // Purple Box datepicker stuff
    $("#DateReceived").datepicker({ dateFormat: "mm/dd/yy" });
    $("#OutDate").datepicker({ dateFormat: "mm/dd/yy" });

    // Silver box datepicker stuff; Also used by Reports
    $("#DateIn").datepicker({ dateFormat: "mm/dd/yy" });
    $("#DateOut").datepicker({ dateFormat: "mm/dd/yy" });

    // Alternate table row colors
    $("table.center > tbody tr:even").css("background-color", "#F2F8FF");
});

如果您能帮我解决这个问题,那将是非常棒的。让我知道您是否还有其他需要。

再次感谢。

其他信息

我想澄清一下,以防有任何混淆: 我有两个 ViewModel: 第一个 ViewModel(称为 PackageInfo)包含从实体框架模型创建的对象实例。 PackageInfo 中的值正在通过内置的“简单”MVC 验证在视图中正确验证。

第二个 ViewModel(称为 PackageVals)包含 DateTime 值。 PackageVals 中的值未在视图中进行验证。

【问题讨论】:

  • 您收到的错误是什么?
  • 我还注意到您的DisplayFormat 属性的值为{0:dd/MM/yyyy},而您的验证表明格式必须为mm/dd/yyyy。这是故意的吗?
  • 我看到错误的唯一一次是表单值被传入,并且它们不是日期值。例如,如果我在 DateIn 字段中传入“24ashugfdahu9ahgahui”,则会收到 String was not recognized as a valid DateTime 错误。我将其捕获在控制器的 try-catch 块中,因此错误永远不会通过,但是用户永远不知道为什么他们没有得到任何响应。
  • 我实际上在编写此代码时发现了 mm/dd/yyyy 错误并在代码中对其进行了更改。我将编辑帖子以匹配。

标签: c# asp.net-mvc-3 entity-framework-4 razor validation


【解决方案1】:

问题最终出现在控制器中,这是我没有在上面发布的唯一代码。我想如果我最初发布了它,那么 @Mystere Man 或任何其他好心试图帮助我的人都会立即拿起它。

发生的情况是,我将 Controller 函数的参数设置为 FormCollection 变量而不是模型变量,因此数据被传入而没有根据模型的验证进行检查。

这是有效的代码:

    [HttpPost]
    public ActionResult RptPkgsRecd(PackageVals model)
    {
        ViewBag.CurrentPage = "reports";
        try
        {
            if (ModelState.IsValid)
            {
                PackageVals pv = new PackageVals();
                pv.dps = regpacksRepository.GetSubmitted(model.datePass.DateIn, model.datePass.DateOut).ToList();
                return View(pv);
            }
            else
            {
                PackageVals pv = null;
                return View(pv);
            }
        }
        catch(SystemException ex)
        {
            var error = ex.ToString();
            this.ModelState.AddModelError(error, ex);
            PackageVals pv = null;
            return View(pv);
        }
    }

【讨论】:

    【解决方案2】:

    使您的 DateTime 值可以为 Null。如果您需要它们,请确保它们具有必需的属性。

    如果您的对象不能为空,那么您需要一个独立于数据模型的视图模型。 ViewModel 允许您根据视图的需要对其进行自定义,而不管数据模型的需要。

    【讨论】:

    • 我会试一试 nullable 并让你知道。感谢您的评论。
    • 使 DateTime 值可以为空并没有改变任何东西。它仍然允许在不检查有效日期格式的情况下将无效字符串从视图传递回控制器。
    • @War2d2 - 那么我不确定你做错了什么,因为我向你保证,使用可为空的日期时间字段将对日期格式进行验证。在测试应用中用一个简单的视图试试,你就会明白我的意思了。
    • 我实现 ViewModel 的方式一定有问题。我什至尝试将日期值移动到他们自己的部分类并在那里应用注释,但仍然没有运气。我会完整地发布 ViewModel、视图和控制器,但那里有几百行代码。
    • 这就是我传递 ViewModel 的方式。我将值作为表单数据而不是模型传递给控制器​​。不需要将 DateTime 变量设为可为空。如果我发布了控制器代码,我想几乎任何人都能够发现它。我只是找错地方了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-17
    • 2011-11-22
    • 1970-01-01
    • 1970-01-01
    • 2010-09-24
    相关资源
    最近更新 更多