español - Formato de fecha y hora en asp.net mvc 4
web forms c# (3)
Ahhhh, ahora está claro. Parece que tienes problemas para vincular el valor. No con mostrarlo en la vista. De hecho, ese es el error del encuadernador de modelo predeterminado. Puede escribir y usar uno personalizado que tenga en cuenta el atributo [DisplayFormat]
en su modelo. He ilustrado una carpeta de modelo personalizado aquí: https://stackoverflow.com/a/7836093/29407
Aparentemente, algunos problemas persisten. Aquí está mi configuración completa que funciona perfectamente bien en ASP.NET MVC 3 y 4 RC.
Modelo:
public class MyViewModel
{
[DisplayName("date of birth")]
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:dd/MM/yyyy}", ApplyFormatInEditMode = true)]
public DateTime? Birth { get; set; }
}
Controlador:
public class HomeController : Controller
{
public ActionResult Index()
{
return View(new MyViewModel
{
Birth = DateTime.Now
});
}
[HttpPost]
public ActionResult Index(MyViewModel model)
{
return View(model);
}
}
Ver:
@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>
}
Registro del archivador de modelo personalizado en Application_Start
:
ModelBinders.Binders.Add(typeof(DateTime?), new MyDateTimeModelBinder());
Y el encuadernador de modelo personalizado en sí mismo:
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);
}
}
Ahora, independientemente de la cultura que hayas configurado en tu web.config (elemento <globalization>
) o la cultura de hebras actual, la carpeta de modelo personalizada usará el DisplayFormat
de fecha del atributo DisplayFormat
al analizar las fechas que DisplayFormat
.
¿Cómo puedo forzar el formato de datetime en asp.net mvc 4? En el modo de visualización, se muestra como quiero, pero en el modelo de edición no aparece. Estoy usando displayfor y editorfor y applyformatineditmode = true con dataformatstring = "{0: dd / MM / yyyy}" Lo que he intentado:
- globalización en web.config (ambos) con mi cultura y uiculture.
- modificando la cultura y la uicultura en application_start ()
- modificador de modelo personalizado para fecha y hora
No tengo idea de cómo forzarlo y necesito ingresar la fecha como dd / MM / aaaa no por defecto.
MÁS INFORMACIÓN: mi viewmodel es así
[DisplayName("date of birth")]
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:dd/MM/yyyy}", ApplyFormatInEditMode = true)]
public DateTime? Birth { get; set; }
a la vista utilizo @Html.DisplayFor(m=>m.Birth)
pero esto funciona como se esperaba (veo el formateo) y para ingresar la fecha utilizo @Html.EditorFor(m=>m.Birth)
pero si intento y una entrada como 13/12/2000 falla con el error de que no es una fecha válida (12/13/2000 y 2000/12/13 funcionan como se esperaba pero necesito dd / MM / aaaa).
El modificador de modelo personalizado se llama en application_start () b / c. No sé dónde más.
Usando <globalization/>
lo he intentado con culture="ro-RO", uiCulture="ro"
y otras culturas que me darían dd / MM / aaaa. También he intentado configurarlo por subproceso en application_start () (aquí hay muchos ejemplos sobre cómo hacerlo)
Por todo lo que leerá esta pregunta: parece que la respuesta de Darin Dimitrov funcionará siempre que no tenga la validación del cliente. Otro enfoque es usar la validación personalizada, incluida la validación del lado del cliente. Me alegro de haberlo descubierto antes de volver a crear toda la aplicación.
Gracias Darin, para mí, para poder publicar en el método de creación, solo funcionó después de que modifiqué el código de BindModel para:
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);
}
Espero que esto pueda ayudar a alguien más ...
Los problemas de validación del cliente pueden ocurrir debido a un error de MVC (incluso en MVC 5) en jquery.validate.unobtrusive.min.js que no acepta el formato de fecha / hora de ninguna manera . Desafortunadamente, tienes que resolverlo manualmente.
Mi solución finalmente funcional:
$(function () {
$.validator.methods.date = function (value, element) {
return this.optional(element) || moment(value, "DD.MM.YYYY", true).isValid();
}
});
Debes incluir antes:
@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")
Puede instalar moment.js usando:
Install-Package Moment.js