使用日期时间输入控件全球化验证问题

时间:2019-02-28 13:15:03

标签: javascript asp.net-mvc validation asp.net-core jquery-globalize

我正在尝试使用cldr-data和全球化功能来验证我在ASP.NET Core MVC Web项目中的输入。

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

尽管可以正确识别逗号分隔符(它接受,并拒绝.作为日期输入,但我无法弄清楚为什么日期被标记为无效。

日期以正确的de dd.mm.yyyy格式显示 enter image description here

创建表单还会显示具有正确格式的输入字段 enter image description here

使用.作为逗号分隔符会导致无效 enter image description here

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

Opera / Chrome

enter image description here enter image description here

边缘

enter image description here enter image description here

Firefox

enter image description here enter image description here

设置 enter image description here

_ValidationScriptsPartial.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>

Create.cshtml

    <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>

MoviesController.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
        });
    }
}

Movie.cs

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; }
}

完整存储库

https://github.com/blfuentes/ASP.NET-Core-Movie-Sample

1 个答案:

答案 0 :(得分:0)

我在尝试设置西班牙文化时遇到了同样的问题,我发现的唯一临时解决方案是替换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);
};

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