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

2 つの問題があります: 1) 開始日を 11/07/2016 23:51 に、終了日を 02/08/2016 00:21 にすると、終了日が開始日よりも前であると見なされるため、検証エラーが発生します。私にはテキストの比較のように思えます。

2) また、2 つの model.start および model.end 日付初期化ステートメントのコメントを外すと、送信時に無効な日付が取得されます。

私はブートストラップdatetimepickerを使用していましたが、ドキュメントの準備ができたときに初期化する場所をコメントアウトしたことに注意してください。私はそれが問題と関係があると思っていましたが、そうではないようです。最終的には、datetimepicker も機能させたいと考えています。

また、私はオーストラリアにいるので、日付の形式は dd/mm/yyyy です。

4

1 に答える 1

1

あなたの HTML ur の Index2 への投稿で、それを Index Convert String Back to DateTime in GreaterThanAttribute in your application and then Compare に変更します。

これを試してください この実装をテストしました

コントローラー

 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 に答える