7

質問

以下のコードはServer、クライアント側ではなく、正常に動作しています。なんで ?


フォームを送信すると、コントロールがBeAValidDate機能して、日付が有効かどうかを確認します。Validateを使用してサーバーにアクセスせずに日付を取得する方法はありますFluent Validationか?

スクリプト

<script src="jquery-1.7.1.min.js" type="text/javascript"></script>
<script src="jquery.validate.js" type="text/javascript"></script>
<script src="jquery.validate.unobtrusive.js" type="text/javascript"></script>

モデル

public class PersonValidator : AbstractValidator<Person>
{
    public PersonValidator()
    {
        RuleFor(x => x.FromDate)
            .NotEmpty()
            .WithMessage("Date is required!")
            .Must(BeAValidDate)
            .WithMessage("Invalid Date");
    }

    private bool BeAValidDate(String value)
    {
        DateTime date;
        return DateTime.TryParse(value, out date);
    }
}

コントローラ

public class PersonController : Controller
{
    public ActionResult Index()
    {
       return View(new Person { FromDate = DateTime.Now.AddDays(2).ToString()});
    }

    [HttpPost]
    public ActionResult Index(Person p)
    {
        return View(p);
    }
}

意見

@using (Html.BeginForm("Index", "Person", FormMethod.Post))
{   
    @Html.LabelFor(x => x.FromDate)
    @Html.EditorFor(x => x.FromDate)
    @Html.ValidationMessageFor(x => x.FromDate)

    <input type="submit" name="Submit" value="Submit" />
}
4

3 に答える 3

6

Greater Then Or Equal To Validator を使用したトリック。私のために働きます。

Global.asax - アプリケーション開始イベント

FluentValidationModelValidatorProvider.Configure(x =>
{
    x.Add(typeof(GreaterThanOrEqualValidator), 
            (metadata, Context, rule, validator) => 
                new LessThanOrEqualToFluentValidationPropertyValidator
                (
                    metadata, Context, rule, validator
                )
            );
});

モデル

[Validator(typeof(MyViewModelValidator))]
public class MyViewModel
{
    [Display(Name = "Start date")]
    [DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", 
                                                  ApplyFormatInEditMode = true)]
    public DateTime StartDate { get; set; }

    [DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", 
                                                  ApplyFormatInEditMode = true)]
    public DateTime DateToCompareAgainst { get; set; }
}

ルール

public class MyViewModelValidator : AbstractValidator<MyViewModel>
{
    public MyViewModelValidator()
    {
        RuleFor(x => x.StartDate)
            .GreaterThanOrEqualTo(x => x.DateToCompareAgainst)
            .WithMessage("Invalid start date");
    }
}

FluentValidationPropertyValidator

public class GreaterThenOrEqualTo : FluentValidationPropertyValidator
{
    public GreaterThenOrEqualTo(ModelMetadata metadata, 
                                ControllerContext controllerContext, 
                                PropertyRule rule, 
                                IPropertyValidator validator)
        : base(metadata, controllerContext, rule, validator)
    {
    }

    public override IEnumerable<ModelClientValidationRule> 
                                                    GetClientValidationRules()
    {
        if (!this.ShouldGenerateClientSideRules())
        {
            yield break;
        }

        var validator = Validator as GreaterThanOrEqualValidator;

        var errorMessage = new MessageFormatter()
            .AppendPropertyName(this.Rule.GetDisplayName())
            .BuildMessage(validator.ErrorMessageSource.GetString());

        var rule = new ModelClientValidationRule{
            ErrorMessage = errorMessage,
            ValidationType = "greaterthanorequaldate"};
        rule.ValidationParameters["other"] = 
            CompareAttribute.FormatPropertyForClientValidation(
                validator.MemberToCompare.Name);
        yield return rule;
    }
}

コントローラ アクション メソッド

public ActionResult Index()
{
    var model = new MyViewModel
    {
        StartDate = DateTime.Now.AddDays(2),
        DateToCompareAgainst = default(DateTime)  //Default Date
    };
    return View(model);
}
[HttpPost]
public ActionResult Index(Practise.Areas.FluentVal.Models.MyViewModel p)
{
    return View(p);
}

意見

@using (Html.BeginForm("Index", "Person", FormMethod.Post, 
                                                new { id = "FormSubmit" }))
{   
    @Html.Hidden("DateToCompareAgainst", Model.DateToCompareAgainst);      
    @Html.LabelFor(x => x.StartDate)
    @Html.EditorFor(x => x.StartDate)
    @Html.ValidationMessageFor(x => x.StartDate)
    <button type="submit">
        OK</button>
}

脚本

<script src="jquery-1.4.1.min.js" type="text/javascript"></script>
<script src="jquery.validate.js" type="text/javascript"></script>
<script src="jquery.validate.unobtrusive.js" type="text/javascript"></script>
<script type="text/javascript">
    (function ($) {
        $.validator.unobtrusive.adapters.add('greaterthanorequaldate', 
                                             ['other'], function (options) {
            var getModelPrefix = function (fieldName) {
                return fieldName.substr(0, fieldName.lastIndexOf(".") + 1);
            };

            var appendModelPrefix = function (value, prefix) {
                if (value.indexOf("*.") === 0) {
                    value = value.replace("*.", prefix);
                }
                return value;
            }

            var prefix          = getModelPrefix(options.element.name),
                other           = options.params.other,
                fullOtherName   = appendModelPrefix(other, prefix),
            element = $(options.form).find(":input[name=" + fullOtherName + 
                                                        "]")[0];

            options.rules['greaterthanorequaldate'] = element;
            if (options.message != null) {
                options.messages['greaterthanorequaldate'] = options.message;
            }
        });

        $.validator.addMethod('greaterthanorequaldate', 
                               function (value, element, params) {
            var date = new Date(value);
            var dateToCompareAgainst = new Date($(params).val());

            if (isNaN(date.getTime()) || isNaN(dateToCompareAgainst.getTime())) {
                return false;
            }
            return date >= dateToCompareAgainst;
        });

    })(jQuery);
</script>
于 2013-08-16T15:00:12.247 に答える
-1

以下の MVC 3 では、コードは正常に動作するはずです。

<script src="@Url.Content("~/Scripts/jquery-1.5.1.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>

@using (Html.BeginForm("Index", "Person", FormMethod.Post))
{   
    @Html.LabelFor(x => x.FromDate)
    @Html.EditorFor(x => x.FromDate)
    @Html.ValidationMessageFor(x => x.FromDate)

    <input type="submit" name="Submit" value="Submit" />
}

MVC 4 での簡単な作業例

_Layout.cshtml:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8" />
        <title>@ViewBag.Title - My ASP.NET MVC Application</title>
        <link href="~/favicon.ico" rel="shortcut icon" type="image/x-icon" />
        <meta name="viewport" content="width=device-width" />


        @Styles.Render("~/Content/css")
        @Scripts.Render("~/bundles/modernizr")
    </head>
    <body>

        <div id="body">
            @RenderSection("featured", required: false)
            <section class="content-wrapper main-content clear-fix">
                @RenderBody()
            </section>
        </div>

        @Scripts.Render("~/bundles/jquery")
        @RenderSection("scripts", required: false)


    </body>
</html>

意見:

@model Mvc4Test.Models.Person

@{
    ViewBag.Title = "test";

}

<h2>test</h2>

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

    <fieldset>
        <legend>Part</legend>

        <div class="editor-label">
            @Html.LabelFor(model => model.Name)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Name)
            @Html.ValidationMessageFor(model => model.Name)
        </div>



        <p>
            <input type="submit" value="Create" />
        </p>
    </fieldset>
}

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

詳細については。

于 2013-08-09T14:27:32.580 に答える