Format datetime w asp.net mvc 4

Jak mogę wymusić format datetime w asp.net mvc 4 ? W trybie wyświetlania wyświetla się tak, jak chcę, ale w modelu edycji nie. Używam displayfor and editorfor and applyformatineditmode = true with dataformatstring= " {0: dd / MM / yyyy}" Czego próbowałem:

    [[8]}globalizacja w sieci.config (oba) z moją kulturą i uiculturą.
  • modyfikowanie Kultury i uiculture w application_start ()
  • custom modelbinder for datetime

Nie mam pojęcia jak Wymuś to i muszę wprowadzić datę jako dd / MM / RRRR, a nie domyślną.

WIĘCEJ INFORMACJI: my viewmodel is like this

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

W widoku używam @Html.DisplayFor(m=>m.Birth) ale to działa zgodnie z oczekiwaniami (widzę formatowanie) a do wprowadzenia daty używam @Html.EditorFor(m=>m.Birth), ale jeśli spróbuję wprowadzić coś w stylu 13/12/2000 to nie powiedzie się z błędem, że nie jest to prawidłowa data (12/13/2000 i 2000/12/13 działają zgodnie z oczekiwaniami, ale potrzebuję dd/MM/RRRR).

Custom modelbinder jest wywoływany w application_start () b / c Nie wiem gdzie indziej.

Używając <globalization/> próbowałem z culture="ro-RO", uiCulture="ro" i innymi kulturami, które dałyby mi dd/MM/RRRR. Próbowałem również ustawić go na zasadzie dla każdego wątku w application_start () (istnieje wiele przykładów tutaj, Jak to zrobić)


Dla wszystkich, którzy przeczytają to pytanie: Wygląda na to, że odpowiedź Darina Dimitrowa będzie działać, dopóki nie będę miał potwierdzenia klienta. Innym podejściem jest użycie walidacji niestandardowej, w tym walidacji po stronie klienta. Cieszę się, że dowiedziałam się o tym wcześniej. odtworzenie całej aplikacji.

Author: casperOne, 2012-06-30

3 answers

Ahhhh, teraz jest jasne. Wydaje się, że masz problemy z przywróceniem wartości. Nie z wyświetlaniem go na widoku. Rzeczywiście, to wina domyślnego segregatora. Możesz napisać i użyć niestandardowego, który weźmie pod uwagę atrybut [DisplayFormat] w twoim modelu. Ilustrowałem tu taki segregator na zamówienie: https://stackoverflow.com/a/7836093/29407


Najwyraźniej niektóre problemy nadal utrzymują się. Oto moja pełna konfiguracja działa idealnie na obu ASP.NET MVC 3 & 4 RC.

Model:

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

Kontroler:

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

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

Widok:

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

Rejestracja modelu niestandardowego w Application_Start:

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

I sam segregator modelu niestandardowego:

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

Teraz, bez względu na kulturę masz skonfigurowany w sieci.config (<globalization> element) lub bieżąca kultura wątku, segregator modelu niestandardowego użyje formatu daty atrybutu DisplayFormat podczas parsowania dat zerowych.

 101
Author: Darin Dimitrov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:03:02

Dzięki Darin, Dla mnie, aby móc pisać do metody create, działało to dopiero po zmodyfikowaniu kodu BindModel do :

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);
}
Mam nadzieję, że to pomoże komuś innemu...
 0
Author: Bashar Abu Shamaa,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-11 08:56:16

Problemy z walidacją klienta mogą wystąpić z powodu błędu MVC (nawet w MVC 5) w jquery./ align = "left" / dyskretny./ min.js który nie akceptuje w żaden sposób formatu date/datetime. Niestety musisz rozwiązać go ręcznie.

Moje wreszcie działające rozwiązanie:

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

Musisz dołączyć przed:

@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")

Możesz zainstalować moment.js using:

Install-Package Moment.js
 0
Author: lukyer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-08 15:57:18