Вопрос по asp.net-mvc-4, asp.net-mvc, datetime-format – Формат даты и времени в asp.net MVC 4

56

Как я могу форсировать формат datetime в asp.net mvc 4? В режиме отображения он отображается так, как я хочу, но в модели редактирования это не так. Я использую displayfor и editorfor и applyformatineditmode = true с dataformatstring = & quot; {0: dd / MM / yyyy} & quot; Что я пробовал:

globalization in web.config (both of them) with my culture and uiculture. modifying the culture and uiculture in application_start() custom modelbinder for datetime

Я понятия не имею, как заставить его, и мне нужно ввести дату как дд / мм / гггг не по умолчанию.

БОЛЬШЕ ИНФОРМАЦИИ: моя модель зрения такая

    [DisplayName("date of birth")]
    [DataType(DataType.Date)]
    [DisplayFormat(DataFormatString = "{0:dd/MM/yyyy}", ApplyFormatInEditMode = true)]
    public DateTime? Birth { get; set; }

ввиду я использую@Html.DisplayFor(m=>m.Birth) но это работает как ожидалось (я вижу форматирование) и ввести дату, которую я использую@Html.EditorFor(m=>m.Birth) но если я попытаюсь ввести что-то вроде 13/12/2000, произойдет сбой с ошибкой, что это недопустимая дата (13.12.2000 и 2000/12/13 работают как положено, но мне нужно dd / MM / гггг) ,

Пользовательский связыватель моделей вызывается в application_start (), потому что я не знаю, где еще.

С помощью<globalization/> Я пробовал сculture="ro-RO", uiCulture="ro" и другие культуры, которые дали бы мне дд / мм / гггг. Я также попытался установить его для каждого потока в application_start () (здесь много примеров того, как это сделать)

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

Nas, где будет application_beginRequest? Я вижу только application_start в Global. В MVC 4 вещи стали немного отличаться от MVC 3 amb
application_start выполняется только один раз! Используйте взамен application_beginRequest! Nas
Не могли бы вы предоставить немного больше информации? Ваша модель, контроллер и вид? Также приведите пример различных результатов, которые вы получаете между дисплеем и шаблоном редактора. Также обратите внимание, что культура настроена на поток. Вы упомянули что-то оApplication_Start но это выполняется только один раз, когда ваше приложение запускается. Как насчет последующих запросов? Как вы устанавливаете культуру для них? Darin Dimitrov

Ваш Ответ

3   ответа
0

Спасибо дарин, Для меня, чтобы иметь возможность публиковать в методе создания, он работал только после того, как я изменил код BindModel:

public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
    var displayFormat = bindingContext.ModelMetadata.DisplayFormatString;
    var value = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);

    if (!string.IsNullOrEmpty(displayFormat) && value != null)
    {
        DateTime date;
        displayFormat = displayFormat.Replace("{0:", string.Empty).Replace("}", string.Empty);
        // use the format specified in the DisplayFormat attribute to parse the date
         if (DateTime.TryParse(value.AttemptedValue, CultureInfo.GetCultureInfo("en-GB"), DateTimeStyles.None, out date))
        {
            return date;
        }
        else
        {
            bindingContext.ModelState.AddModelError(
                bindingContext.ModelName,
                string.Format("{0} is an invalid date format", value.AttemptedValue)
            );
        }
    }

    return base.BindModel(controllerContext, bindingContext);
}

Надеюсь, что это может помочь кому-то еще ...

1

Проблемы проверки клиента могут возникнуть из-за ошибки MVC (даже в MVC 5) вjquery.validate.unobtrusive.min.js которыйdoes not accept date/datetime format in any way, К сожалению, вы должны решить это вручную.

My finally working solution:

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

Вы должны включить до:

@Scripts.Render("~/Scripts/jquery-3.1.1.js")
@Scripts.Render("~/Scripts/jquery.validate.min.js")
@Scripts.Render("~/Scripts/jquery.validate.unobtrusive.min.js")
@Scripts.Render("~/Scripts/moment.js")

Вы можете установить moment.js используя:

Install-Package Moment.js
103

Аааа, теперь понятно. Кажется, у вас есть проблемы с привязкой значения. Не с отображением в представлении. Действительно, это ошибка связующего устройства модели по умолчанию. Вы можете написать и использовать пользовательский, который будет учитывать[DisplayFormat] атрибут вашей модели. Я проиллюстрировал такую пользовательскую модель переплета:https://stackoverflow.com/a/7836093/29407


По-видимому, некоторые проблемы все еще сохраняются. Вот моя полная установка, прекрасно работающая на обоих ASP.NET MVC 3 & amp; 4 RC.

Модель:

public class MyViewModel
{
    [DisplayName("date of birth")]
    [DataType(DataType.Date)]
    [DisplayFormat(DataFormatString = "{0:dd/MM/yyyy}", ApplyFormatInEditMode = true)]
    public DateTime? Birth { get; set; }
}

контроллер:

public class HomeController : Controller
{
    public ActionResult Index()
    {
        return View(new MyViewModel
        {
            Birth = DateTime.Now
        });
    }

    [HttpPost]
    public ActionResult Index(MyViewModel model)
    {
        return View(model);
    }
}

Посмотреть:

@model MyViewModel

@using (Html.BeginForm())
{
    @Html.LabelFor(x => x.Birth)
    @Html.EditorFor(x => x.Birth)
    @Html.ValidationMessageFor(x => x.Birth)
    <button type="submit">OK</button>
}

Регистрация пользовательской модели переплета вApplication_Start:

ModelBinders.Binders.Add(typeof(DateTime?), new MyDateTimeModelBinder());

И пользовательская модель переплета сама по себе:

public class MyDateTimeModelBinder : DefaultModelBinder
{
    public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        var displayFormat = bindingContext.ModelMetadata.DisplayFormatString;
        var value = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);

        if (!string.IsNullOrEmpty(displayFormat) && value != null)
        {
            DateTime date;
            displayFormat = displayFormat.Replace("{0:", string.Empty).Replace("}", string.Empty);
            // use the format specified in the DisplayFormat attribute to parse the date
            if (DateTime.TryParseExact(value.AttemptedValue, displayFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out date))
            {
                return date;
            }
            else
            {
                bindingContext.ModelState.AddModelError(
                    bindingContext.ModelName,
                    string.Format("{0} is an invalid date format", value.AttemptedValue)
                );
            }
        }

        return base.BindModel(controllerContext, bindingContext);
    }
}

Теперь, независимо от того, какую культуру вы настроили в своем web.config (<globalization> элемент) или текущую культуру потока, пользовательский связыватель модели будет использоватьDisplayFormat формат даты атрибута при разборе значений Nullable.

Тогда я думаю, вам придется показать свой полный код, позволяющий нам воспроизвести проблему, потому что я использую эту модель без каких-либо проблем.
Из любопытства, что это за проект MVC (4 или 3)? amb
Это тот, который я использовал, но без удачи. Я зарегистрировал это как с datetime, так и с datetime? Он даже не показывает мое сообщение об ошибке, поэтому я не думаю, что оно привыкло. amb
Протестировано и работает на ASP.NET MVC 3 & amp; 4 RC. Я обновил свой ответ своим полным рабочим примером. Теперь возникает вопрос: чем ваша установка отличается от моей, и не могли бы вы привести полный пример (как я это сделал), позволяющий нам воспроизвести проблему, с которой вы столкнулись. В противном случае я не вижу, как я мог бы помочь вам в дальнейшем.
Я проверил ваш пример, и он работает. Забавно, что в моем полном приложении оно все еще не может быть связано. Что у меня есть от вас - это @helper в представлении, так что я могу легко вставлять поля. Мне придется воссоздать все приложение и посмотреть, где оно перестает работать. Но, кроме этого, этот глюк (с моей стороны), ваша пользовательская модель переплета идеально. amb

Похожие вопросы