MVC 5 неправильно проверяет поле модели с пользовательской аннотацией DateTime - PullRequest
0 голосов
/ 02 марта 2019

В моем проекте ASP.NET MVC 5 я добавил DataAnnotation для форматирования поля DateTime модели, например "dd / mm / yyyy", однако, когда поле отображается в представлении редактирования с помощью @ Html.Editor, это все еще проверяется.как дата типа «мм / дд / гггг» (например, если я вставляю дату, например «13/12/2019», я получаю сообщение об ошибке, поскольку 13-й день считается месяцем).

ЭтоМодель сущностей, сгенерированная из базы данных:

namespace MyProject
{
    using System;
    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations;

    public partial class Supplier
    {
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
        public Supplier()
        {
            this.Brands = new HashSet<Brand>();
        }

        public long Id { get; set; }
        public string Name { get; set; }
        public string Agent { get; set; }
        public string Address { get; set; }
        public string Phone { get; set; }
        public string Email { get; set; }

        public Nullable<System.DateTime> NextOrderDate { get; set; }

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
        public virtual ICollection<Brand> Brands { get; set; }
    }
}

Я использую обходной путь , описанный здесь , чтобы добавить DataAnnotations, чтобы они не стирались при регенерации сущностей из базы данных, поэтому я добавилтакже этот класс метаданных:

namespace MyProject
{
    using System;
    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations;

    [MetadataType(typeof(SupplierMetadata))]
    public partial class Supplier
    {
        // Note this class has nothing in it.  It's just here to add the class-level attribute.
    }

    public class SupplierMetadata
    {
        [Required]
        public string Name { get; set; }

        [Required]
        public string Agent { get; set; }

        [Required]
        public string Address { get; set; }

        [Required]
        public string Phone { get; set; }

        [Required]
        public string Email { get; set; }

        [Display(Name = "Next Order")]
        [DisplayFormat(DataFormatString = "{0:dd/mm/yyyy}")]
        public Nullable<System.DateTime> NextOrderDate { get; set; }

    }

И вот как отображается мое поле:

<div class="form-group">
    @Html.LabelFor(model => model.NextOrderDate, htmlAttributes: new { @class = "col-form-label col-lg-2" })
    <div class="col-lg-10">
        @Html.EditorFor(model => model.NextOrderDate, new { htmlAttributes = new { @class = "form-control" } })
        @Html.ValidationMessageFor(model => model.NextOrderDate, "", new { @class = "text-danger" })
    </div>
</div>

Я также добавил этот код в Global.asax.cs, но ничего не изменилось:

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Threading;
using System.Web;
using System.Web.Mvc;
using System.Web.Optimization;
using System.Web.Routing;

namespace MyProject
{
    public class MvcApplication : System.Web.HttpApplication
    {
        protected void Application_Start()
        {

            CultureInfo newCulture = (CultureInfo)Thread.CurrentThread.CurrentCulture.Clone();
            newCulture.DateTimeFormat.ShortDatePattern = "dd/mm/yyyy";
            newCulture.DateTimeFormat.DateSeparator = "/";
            Thread.CurrentThread.CurrentCulture = newCulture;

            AreaRegistration.RegisterAllAreas();
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);
        }
    }
}

1 Ответ

0 голосов
/ 02 марта 2019

Я решил эту проблему из-за того, что проверка jQuery не учитывала культуру при разборе даты.Если вы отключите проверку на стороне клиента, дата будет точно проанализирована на сервере, который знает о культуре.Исправление состоит в том, чтобы переопределить проверку jQuery для даты и включить дополнительный плагин глобализации jQuery.

Мое окончательно работающее решение -

  • Установить момент.js, используя:

    Install-Package Moment.js

И затем добавить исправление для анализатора формата даты в представлении:

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

    <script>


        $(function () {
            $.validator.methods.date = function (value, element) {
                return this.optional(element) || moment(value, "DD/MM/YYYY", true).isValid();
            }
        });
    </script>
}
...