1

我在 MVC 项目中使用万无一失。我在进行文本比较以确定结束日期时间是否大于开始日期时间时遇到问题。

这是模型:

public class TestModel
{
    [Required]
    [DataType(DataType.DateTime)]
    public DateTime start { get; set; }

    [Required]
    [DataType(DataType.DateTime)]
    [GreaterThan("start")]
    public DateTime end { get; set; }
}

风景

@model WebApplication1.Models.TestModel

@{
    ViewBag.Title = "Home Page";
}


@using (Html.BeginForm("Index2", "Home", FormMethod.Post, new { @class = "form-horizontal", role = "form" }))
{
    @Html.AntiForgeryToken()

    @Html.ValidationSummary("", new { @class = "text-danger" })
    <div class="form-group">
        @Html.LabelFor(m => m.start, new { @class = "col-md-2 control-label" })
        <div class="col-md-10">
            @Html.TextBoxFor(m => m.start, "{0:dd/MM/yyyy HH:mm}", new { @class = "form-control datetimepicker" })
        </div>
    </div>
    <div class="form-group">
        @Html.LabelFor(m => m.end, new { @class = "col-md-2 control-label" })
        <div class="col-md-10">
            @Html.TextBoxFor(m => m.end, "{0:dd/MM/yyyy HH:mm}", new { @class = "form-control datetimepicker" })
        </div>
    </div>
    <div class="form-group">
        <div class="col-md-offset-2 col-md-10">
            <input type="submit" value="Set password" class="btn btn-default" />
        </div>
    </div>
}

@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
}

控制器

    public ActionResult Index()
    {
        TestModel model = new TestModel();
        // model.start = new DateTime(2016, 5, 31);
        //model.end = new DateTime(2016, 8, 31);
        model.start = DateTime.Now;
        model.end = DateTime.Now.AddMinutes(30);
        return View(model);
    }

你可以下载我的项目来试用: https ://www.dropbox.com/s/pf0lkg297hq0974/WebApplication1.zip?dl=0

有两个问题:1)当您将开始日期设为 11/07/2016 23:51 和结束日期为 02/08/2016 00:21 时,您会收到验证错误,因为它认为结束日期小于开始日期。对我来说,这似乎是一个文本比较。

2)此外,如果您取消注释掉两个 model.start 和 model.end 日期初始化语句,您在提交时会得到无效日期。

请注意,我使用的是引导程序 datetimepicker,但注释掉了在文档准备好时初始化它的位。我认为这与问题有关,但似乎没有。最终我想让 datetimepicker 也能正常工作。

另请注意,我在澳大利亚,因此日期格式为 dd/mm/yyyy

4

1 回答 1

1

在您发布到 Index2 的 HTML 中,将其更改为应用程序中 GreaterThanAttribute 中的 Index Convert String Back to DateTime,然后进行比较

试试这个我已经测试过这个实现

控制器

 public class TestController : Controller
{
    // GET: Test

    [HttpGet]
    public ActionResult Index()
    {

        var model = new TestModel();
        // model.start = new DateTime(2016, 5, 31);
        //model.end = new DateTime(2016, 8, 31);
        model.start = DateTime.Now;
        model.end = DateTime.Now.AddMinutes(30);
        return View(model);


    }
    [HttpPost]
    public ActionResult Index(TestModel model)
    {
        if (ModelState.IsValid)
        {

            // model.start = new DateTime(2016, 5, 31);
            //model.end = new DateTime(2016, 8, 31);
            model.start = DateTime.Now;
            model.end = DateTime.Now.AddMinutes(30);
             return View("Index", model);
        }
        return View("Index", model);

    }
}

你的测试模型

public class TestModel
{
    [Required]
    [DataType(DataType.DateTime)]
    public DateTime start { get; set; }

    [Required]
    [DataType(DataType.DateTime)]
    [GreaterThan("start", "Your Error Message")]
    public DateTime end { get; set; }
}

你的 GreaterThenAttribute.cs

 public class GreaterThanAttribute : ValidationAttribute, IClientValidatable
{

    public string otherPropertyName;
    public GreaterThanAttribute()
    {
    }
    public GreaterThanAttribute(string otherPropertyName, string errorMessage) : base(errorMessage)
    {
        this.otherPropertyName = otherPropertyName;
    }

    protected override ValidationResult IsValid
        (object value, ValidationContext validationContext)
    {
        ValidationResult validationResult = ValidationResult.Success;
        try
        {
            // Using reflection we can get a reference to the other date property, in this example the project start date
            var containerType = validationContext.ObjectInstance.GetType();
            var field = containerType.GetProperty(this.otherPropertyName);
            var extensionValue = field.GetValue(validationContext.ObjectInstance, null);
            var datatype = extensionValue.GetType();

            //var otherPropertyInfo = validationContext.ObjectInstance.GetType().GetProperty(this.otherPropertyName);
            if (field == null)
                return new ValidationResult(String.Format("Unknown property: {0}.", otherPropertyName));
            // Let's check that otherProperty is of type DateTime as we expect it to be
            if ((field.PropertyType == typeof(DateTime) ||
                 (field.PropertyType.IsGenericType && field.PropertyType == typeof(Nullable<DateTime>))))
            {
                DateTime toValidate = (DateTime)value;
                DateTime referenceProperty = (DateTime)field.GetValue(validationContext.ObjectInstance, null);
                // if the end date is lower than the start date, than the validationResult will be set to false and return
                // a properly formatted error message
                if (toValidate.CompareTo(referenceProperty) < 1)
                {
                    validationResult = new ValidationResult(ErrorMessageString);
                }
            }
            else
            {
                validationResult = new ValidationResult("An error occurred while validating the property. OtherProperty is not of type DateTime");
            }
        }
        catch (Exception ex)
        {
            // Do stuff, i.e. log the exception
            // Let it go through the upper levels, something bad happened
            throw ex;
        }

        return validationResult;
    }

    public IEnumerable<ModelClientValidationRule> GetClientValidationRules
        (ModelMetadata metadata, ControllerContext context)
    {
        var rule = new ModelClientValidationRule
        {
            ErrorMessage = FormatErrorMessage(metadata.GetDisplayName()),
            ValidationType = "isgreater",
        };
        rule.ValidationParameters.Add("otherproperty", otherPropertyName);
        yield return rule;
    }
}
于 2016-08-01T14:35:52.080 回答