Javascript 使用datetime输入控件全球化验证问题

Javascript 使用datetime输入控件全球化验证问题,javascript,asp.net-mvc,validation,asp.net-core,jquery-globalize,Javascript,Asp.net Mvc,Validation,Asp.net Core,Jquery Globalize,我试图使用cldr数据和全球化功能来验证我在ASP.NET核心MVC web项目中的输入 出现问题是因为它似乎可以基于navigator.language属性加载正确的cldr数据文件(我知道这并不总是准确的,但在这种情况下应该是有效的。我的操作系统设置为en US,浏览器有三种显示为“de”的语言,并且是navigator.languages列表的第一种语言) 虽然逗号分隔符被正确识别(它接受日期输入的、和拒绝),但我无法理解为什么日期被标记为无效 日期以正确的dedd.mm.yyyy格式显示

我试图使用cldr数据和全球化功能来验证我在ASP.NET核心MVC web项目中的输入

出现问题是因为它似乎可以基于
navigator.language
属性加载正确的cldr数据文件(我知道这并不总是准确的,但在这种情况下应该是有效的。我的操作系统设置为en US,浏览器有三种显示为“de”的语言,并且是
navigator.languages
列表的第一种语言)

虽然逗号分隔符被正确识别(它接受日期输入的
和拒绝
),但我无法理解为什么日期被标记为无效

日期以正确的
de
dd.mm.yyyy
格式显示

创建表单还显示格式正确的输入字段

用作逗号分隔符会引发无效的错误

使用datetimepicker选择器会给我一个无效的日期

Opera/Chrome

边缘

Firefox

设置

\u validationscripttial.cshtml

<environment include="Development">
    <script src="~/lib/jquery-validation/dist/jquery.validate.js"></script>
    <script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js"></script>

    <!-- cldr scripts (needed for globalize) -->
    <script src="~/lib/cldrjs/dist/cldr.js"></script>
    <script src="~/lib/cldrjs/dist/cldr/event.js"></script>
    <script src="~/lib/cldrjs/dist/cldr/supplemental.js"></script>
    <!-- globalize scripts -->
    <script src="~/lib/globalize/dist/globalize.js"></script>
    <script src="~/lib/globalize/dist/globalize/number.js"></script>
    <script src="~/lib/globalize/dist/globalize/date.js"></script>

    <script src="~/lib/jquery-validation-globalize/jquery.validate.globalize.js"></script>

</environment>
<environment exclude="Development">
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.17.0/jquery.validate.min.js"
            asp-fallback-src="~/lib/jquery-validation/dist/jquery.validate.min.js"
            asp-fallback-test="window.jQuery && window.jQuery.validator"
            crossorigin="anonymous"
            integrity="sha256-F6h55Qw6sweK+t7SiOJX+2bpSAa3b/fnlrVCJvmEj1A=">
    </script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validation-unobtrusive/3.2.11/jquery.validate.unobtrusive.min.js"
            asp-fallback-src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js"
            asp-fallback-test="window.jQuery && window.jQuery.validator && window.jQuery.validator.unobtrusive"
            crossorigin="anonymous"
            integrity="sha256-9GycpJnliUjJDVDqP0UEu/bsm9U+3dnQUH8+3W10vkY=">
    </script>
</environment>

<script type="text/javascript">
    function setGlobalization() {
        debugger;
        var url = "@Url.Action("GetBrowserLanguage", "Movies")";
        $.ajax({
            cache: false,
            type: 'GET',
            url: url,
            data: { navigatorlanguage: navigator.language }
        }).done(function (result) {
            debugger;
            $.when(
                $.get("/lib/cldr-data/supplemental/likelySubtags.json"),
                $.get("/lib/cldr-data/main/" + result.language + "/numbers.json"),
                $.get("/lib/cldr-data/supplemental/numberingSystems.json"),
                $.get("/lib/cldr-data/main/" + result.language + "/ca-gregorian.json"),
                $.get("/lib/cldr-data/main/" + result.language + "/timeZoneNames.json"),
                $.get("/lib/cldr-data/supplemental/timeData.json"),
                $.get("/lib/cldr-data/supplemental/weekData.json")
            ).then(function () {
                debugger;
                // Normalize $.get results, we only need the JSON, not the request statuses.
                return [].slice.apply(arguments, [0]).map(function (result) {
                    return result[0];
                });
            }).then(Globalize.load).then(function () {
                debugger;
                Globalize.locale(result.language);
            });
        }).fail(function (result) {
            alert("Server error(setGlobalization): " + result.statusText + " Please refresh and try again");
        });
    }
    document.addEventListener('DOMContentLoaded', function () {
        setGlobalization();
    }, false);

</script>
    <form asp-action="Create">
        <div asp-validation-summary="ModelOnly" class="text-danger"></div>
        <div class="form-group">
            <label asp-for="Title" class="control-label"></label>
            <input asp-for="Title" class="form-control" />
            <span asp-validation-for="Title" class="text-danger"></span>
        </div>
        <div class="form-group">
            <label asp-for="ReleaseData" class="control-label"></label>
            <input asp-for="ReleaseData" class="form-control" />
            <span asp-validation-for="ReleaseData" class="text-danger"></span>
        </div>
        <div class="form-group">
            <label asp-for="Genre" class="control-label"></label>
            <input asp-for="Genre" class="form-control" />
            <span asp-validation-for="Genre" class="text-danger"></span>
        </div>
        <div class="form-group">
            <label asp-for="Price" class="control-label"></label>
            <input asp-for="Price" class="form-control" />
            <span asp-validation-for="Price" class="text-danger"></span>
        </div>
        <div class="form-group">
            <input type="submit" value="Create" class="btn btn-primary" />
        </div>
    </form>
Movie.cs

public ActionResult GetBrowserLanguage(string navigatorlanguage)
{
    try
    {
        string localePattern = "lib\\cldr-data\\main\\{0}";
        var cultureToUse = "es-ES"; //Default regionalisation to use
        string defaultLanguage = "es";

        if (navigatorlanguage.StartsWith("es", StringComparison.InvariantCultureIgnoreCase))
            cultureToUse = "es";
        if (navigatorlanguage.StartsWith("de", StringComparison.InvariantCultureIgnoreCase))
            cultureToUse = "de";
        if (navigatorlanguage.StartsWith("en", StringComparison.InvariantCultureIgnoreCase))
            cultureToUse = "en-US-POSIX";

        if (!System.IO.Directory.Exists(System.IO.Path.Combine(_hostingEnvironment.WebRootPath, string.Format(localePattern, cultureToUse))))
            cultureToUse = defaultLanguage;

        return Json(new
        {
            error = false,
            exception = false,
            language = cultureToUse
        });
    }
    catch (Exception ex)
    {
        return Json(new
        {
            error = true,
            exception = true,
            statusText = ex.Message
        });
    }
}
public class Movie
{
    public int Id { get; set; }
    public string Title { get; set; }
    [DataType(DataType.Date)]
    public DateTime ReleaseData { get; set; }
    public string Genre { get; set; }
    public decimal Price { get; set; }
}
完整存储库


我在尝试设置西班牙文化时遇到了同样的问题,我找到的唯一临时解决方案是替换jquery.validate.globalize.js中的validator.methods.date函数

$.validator.methods.date = function (value, element) {
    var fecha = new Date(value);
    var dia = fecha.getDate() + 1;
    var mes = fecha.getMonth() + 1;
    var anio = fecha.getFullYear();
    if (dia < 10) {
        dia = '0' + dia;
    };
    if (mes < 10) {
        mes = '0' + mes;
    };
    var newValue = dia + '/' + mes + '/' + anio;
    var val = Globalize.parseDate(newValue, $.validator.methods.dateGlobalizeOptions.dateParseFormat);
    return this.optional(element) || (val instanceof Date);
};
$.validator.methods.date=函数(值,元素){
var fecha=新日期(值);
var dia=fecha.getDate()+1;
var mes=fecha.getMonth()+1;
var anio=fecha.getFullYear();
如果(直径<10){
直径='0'+直径;
};
如果(mes<10){
mes='0'+mes;
};
var newValue=dia+'/'+mes+'/'+anio;
var val=Globalize.parseDate(newValue,$.validator.methods.dateGlobalizeOptions.dateParseFormat);
返回此。可选(元素)| |(val instanceof Date);
};

也许这不是最好的解决方案,但这是我实现日期验证的唯一方法。

你有没有找到更好的解决方案?(覆盖验证器方法)。@rufo遗憾的是没有。我认为在最后进行模式检查并在提交时执行转换将是一种方法。