Puedo obtener una Fecha en un ASP.NET Núcleo del Controlador como este:

public class MyController:Controller{
    public IActionResult Test(DateTime date) {

    }
}

El marco es capaz de analizar la fecha, pero sólo en inglés formato. Cuando me pase 04.12.2017 como parámetro de fecha, me refiero a que el 4 de diciembre de 2017. Este sería analizada como inglés fecha, así que mi fecha de objetos obtiene el valor de 12 de abril de 2017. He intentado añadir alemán sólo mediante este artículo y también este, pero sin éxito.

Lo que se necesita hacer que ASP.NET Núcleo analiza automáticamente las fechas en la correcta alemán formato?

Actualización
He Tratado de establecer el RequestLocalizationOptions

services.Configure<RequestLocalizationOptions>(opts =>
{
    var supportedCultures = new[]
    {
        new CultureInfo("de-DE"),
    };

    opts.DefaultRequestCulture = new RequestCulture("de-DE");
    //Formatting numbers, dates, etc.
    opts.SupportedCultures = supportedCultures;
    //UI strings that we have localized.
    opts.SupportedUICultures = supportedCultures;
});

Todavía no está trabajando. Yo llame example.com/Test?date=12.04.2017 y tengo esta en mi depurador:

public IActionResult Test(DateTime date) {
    string dateString = date.ToString("d"); //04.12.2016
    string currentDateString = DateTime.Now.ToString("d"); //14.01.2016
    return Ok();
}
Cómo la están pasando en las fechas en las que se va a analizar, mostrar el formato de la URL que hacer.
Como dije: Una llamada con la Prueba?fecha=12.04.2017 parámetro de resultados en 04.12.2017 como la fecha de objetos dentro de la función de Prueba. Espero que el sin modificar la fecha, por lo 12.04.2017 en lugar de 04.12.2017.
Pasamos como una cadena, a continuación, utilizar DateTime.ParseExact analizarlo exactamente de la manera que usted desea.
Para un punto de claridad (a la ayuda de discusión) 04.12.2017 siendo 4 de diciembre de es formato de inglés, o más precisamente el inglés británico. Siendo 12 de abril se NOS inglés formato. Aunque el reino unido el uso de un / en lugar de una . como un separador.
hola @Lion me pega el Inicio.cs para asp.net núcleo del tipo de proyecto y establecer la cultura de la información . cuando miré a la cultura actual en mi controlador se establece en DE . Por favor, intente esto si que esta ayuda . Traté de que me mostró fechas DE formato . No he probado con el parámetro en el controlador de bits om ventana Inmediato .

OriginalEl autor Lion | 2017-01-13

9 Comentarios

  1. 11

    Tenía el mismo problema. Al pasar DateTime en la solicitud de cuerpo funciona bien (porque Json convertidor controla este personal), pasando DateTime en la cadena de consulta como un parámetro tiene algunos problemas de la cultura.

    No me gusta el «cambio de todas las solicitudes de la cultura», ya que esto podría tener un impacto en otro tipo de análisis, lo cual no es deseable.

    Así que mi elección fue para reemplazar el valor predeterminado DateTime modelo de unión con IModelBinder: https://docs.microsoft.com/en-us/aspnet/core/mvc/advanced/custom-model-binding

    Lo que yo hice:

    1) Definir el cuaderno (c# 7 sintaxis para ‘salir’ parámetro se utiliza):

    public class DateTimeModelBinder : IModelBinder
    {
        public Task BindModelAsync(ModelBindingContext bindingContext)
        {
            if (bindingContext == null)
                throw new ArgumentNullException(nameof(bindingContext));
    
            //Try to fetch the value of the argument by name
            var modelName = bindingContext.ModelName;
            var valueProviderResult = bindingContext.ValueProvider.GetValue(modelName);
            if (valueProviderResult == ValueProviderResult.None)
                return Task.CompletedTask;
    
            bindingContext.ModelState.SetModelValue(modelName, valueProviderResult);
    
            var dateStr = valueProviderResult.FirstValue;
            //Here you define your custom parsing logic, i.e. using "de-DE" culture
            if (!DateTime.TryParse(dateStr, new CultureInfo("de-DE"), DateTimeStyles.None, out DateTime date))
            {
                bindingContext.ModelState.TryAddModelError(bindingContext.ModelName, "DateTime should be in format 'dd.MM.yyyy HH:mm:ss'");
                return Task.CompletedTask;
            }
    
            bindingContext.Result = ModelBindingResult.Success(date);
            return Task.CompletedTask;
        }
    }

    2) Definir proveedor para su cuaderno:

     public class DateTimeModelBinderProvider : IModelBinderProvider
    {
        public IModelBinder GetBinder(ModelBinderProviderContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }
    
            if (context.Metadata.ModelType == typeof(DateTime) || 
                context.Metadata.ModelType == typeof(DateTime?))
            {
                return new DateTimeModelBinder();
            }
    
            return null;
        }
    }

    3) Y, por último, registrar su proveedor para ser utilizado por ASP.NET Núcleo:

    services.AddMvc(options =>
    {
        options.ModelBinderProviders.Insert(0, new DateTimeModelBinderProvider());
    });

    Ahora su DateTime se analiza como se esperaba.

    Trabajó como un encanto. Gracias!
    la Documentación de Microsoft sugiere no utilizar Personalizado cuadernos de modelo para la conversión de cadenas a otros tipos, como la mejor práctica: Normalmente no debería ser usado para convertir una cadena en un tipo personalizado, un TypeConverter es generalmente la mejor opción.. Considere el uso de TypeConverter
    Gracias, trabajó también para mí. Sólo una nota: el modelo de cuaderno de arriba es que no manejo bien DateTime? los valores null.

    OriginalEl autor Igor Fedchenko

  2. 7

    Quería formato de las fechas en mis respuestas y me hizo la siguiente en ConfigureServices método:

    services.AddMvc()
    .AddJsonOptions(options =>
    {
        options.SerializerSettings.DateFormatString = "mm/dd/yy, dddd";
    });

    Espero que ayude.

    Gracias. Si sólo desea utilizar para un caso en particular puede ser especificado al convertir así var deserialized = JsonConvert.DeserializeObject(myJsonstring, new JsonSerializerSettings { DateFormatString = "dd/MM/yyyy" });
    esto fue muy útil, gracias!

    OriginalEl autor PayamGerami

  3. 2

    MVC siempre ha utilizado InvariantCulture para los datos de la ruta y las cadenas de consulta (con los parámetros que ir en la dirección URL). La razón detrás de esto es que las Url en la aplicación localizada de ser universal. De lo contrario, uno de url puede proporcionar datos diferentes dependiendo de la configuración regional del usuario.

    Puede reemplazar la consulta y la ruta ValueProviderFactories con tu propia cuenta de que el respeto de la cultura actual (o el uso de method="POST" en formularios)

    public class CustomValueProviderFactory : IValueProviderFactory
    {
        public Task CreateValueProviderAsync(ValueProviderFactoryContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }
    
            var query = context.ActionContext.HttpContext.Request.Query;
            if (query != null && query.Count > 0)
            {
                var valueProvider = new QueryStringValueProvider(
                    BindingSource.Query,
                    query,
                    CultureInfo.CurrentCulture);
    
                context.ValueProviders.Add(valueProvider);
            }
    
            return Task.CompletedTask;
        }
    }
    
    services.AddMvc(opts => {
        //2 - Index QueryStringValueProviderFactory
        opts.ValueProviderFactories[2] = new CustomValueProviderFactory(); 
    })

    P. S. es una conducta razonable, pero no entiendo por que la documentación no cubren esta cosa muy importante.

    OriginalEl autor Sergei Shvets

  4. 0
                  using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Threading.Tasks;
    using Microsoft.AspNetCore.Builder;
    using Microsoft.AspNetCore.Hosting;
    using Microsoft.Extensions.Configuration;
    using Microsoft.Extensions.DependencyInjection;
    using Microsoft.Extensions.Logging;
    using Microsoft.Extensions.Options;
    using System.Globalization;
    using Microsoft.AspNetCore.Localization;
    namespace coreweb
    {
    public class Startup
    {
    public Startup(IHostingEnvironment env)
    {
    var builder = new ConfigurationBuilder()
    .SetBasePath(env.ContentRootPath)
    .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
    .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
    .AddEnvironmentVariables();
    if (env.IsDevelopment())
    {
    //This will push telemetry data through Application Insights pipeline faster, allowing you to view results immediately.
    builder.AddApplicationInsightsSettings(developerMode: true);
    }
    Configuration = builder.Build();
    }
    public IConfigurationRoot Configuration { get; }
    //This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
    //... previous configuration not shown
    services.AddMvc();
    services.Configure<RequestLocalizationOptions>(
    opts =>
    {
    var supportedCultures = new[]
    {
    new CultureInfo("de-DE"),
    };
    opts.DefaultRequestCulture = new RequestCulture("de-DE");
    //Formatting numbers, dates, etc.
    opts.SupportedCultures = supportedCultures;
    //UI strings that we have localized.
    opts.SupportedUICultures = supportedCultures;
    });
    }
    //This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
    {
    loggerFactory.AddConsole(Configuration.GetSection("Logging"));
    loggerFactory.AddDebug();
    //  app.UseApplicationInsightsRequestTelemetry();
    if (env.IsDevelopment())
    {
    app.UseDeveloperExceptionPage();
    app.UseBrowserLink();
    }
    else
    {
    app.UseExceptionHandler("/Home/Error");
    }
    // app.UseApplicationInsightsExceptionTelemetry();
    app.UseStaticFiles();
    var options = app.ApplicationServices.GetService<IOptions<RequestLocalizationOptions>>();
    app.UseRequestLocalization(options.Value);
    app.UseMvc(routes =>
    {
    routes.MapRoute(
    name: "default",
    template: "{controller=Home}/{action=Index}/{id?}");
    });
    }
    }
    }
    No de trabajo. Se aplica a DateTime.Now pero no el argumento que dieron analizados desde el parámetro GET. Por favor, ver mi edición en la pregunta la causa de que sea demasiado largo para un comentario.
    ohhh . déjame que consulte con su editada respuesta . solo para confirmar lo que debe ser el resultado correcto en este caso ?
    12.04.2017 como entrada debe ser analizado como el 12 de abril de 2014 lugar el 4 de diciembre de 2014 como ASP.NET no.

    OriginalEl autor Yashveer Singh

  5. 0

    Si usted no cuenta con el genérico StatusCode método para hacer esta llamada, usted puede hacer algo como lo siguiente:

    internal IActionResult CreateResponse(int code, object content = null)
    {
    Type t = content?.GetType();
    bool textContent = t == typeof(string) || t == typeof(bool);
    //
    JsonSerializerSettings dateFormatSettings = new JsonSerializerSettings
    {
    DateFormatString = myDateFormat
    };
    string bodyContent = content == null || string.IsNullOrWhiteSpace(content + "")
    ? null
    : textContent
    ? content + ""
    : JsonConvert.SerializeObject(content, dateFormatSettings);
    ObjectResult or = base.StatusCode(code, bodyContent);
    string mediaType = 
    !textContent
    ? "application/json"
    : "text/plain";
    or.ContentTypes.Add(new MediaTypeHeaderValue(mediaType));
    return or;
    }

    Puede agregar esto a una clase base y llamarlo como:

    return base.CreateResponse(StatusCodes.Status200OK, new { name = "My Name", age = 23});

    Es hasta usted si usted desea crear su propia Aceptar, BadRequest, etc…métodos, pero para mí funciona esto y espero que ayude a alguien más. Usted podría incluso defecto int codigo = 200, si la mayoría de las solicitudes se Obtiene. Este código se supone que se quiere responder con una cadena, booleano o un objeto personalizado, pero se puede manejar fácilmente todas las primitivas mediante la comprobación de Tipo.GetTypeInfo().IsPrimitive e incluso haciendo algunas comprobaciones decimal, cadena, DateTime, Lapso de tiempo, DateTimeOffset, o Guid.

    OriginalEl autor pqsk

  6. 0

    Yo tenía el mismo problema anuncio casi se enfadó. He intentado todo sin sucsses. Primero encontré una solución para resolver parte de mi problema:

    Solución:

    string data1 
    string horainicio 
    string horafim
    var ageData = new AgendaData();
    var user = await _userManager.GetUserAsync(User);
    string usuario = user.Id;
    int empresa = user.IdEmpresa;
    int Idprospect = Convert.ToInt32(prospect);
    int minutos = 0;           
    var tipoAgenda = TipoAgenda.Contato;
    var provider = CultureInfo.InvariantCulture;
    provider = new CultureInfo("en-US");            
    string formato = "dd/MM/yyyy HH:mm";
    var dataInicio = DateTime.ParseExact(data1 + " " + horainicio, formato, provider);
    var dataFim = DateTime.ParseExact(data1 + " " + horafim, formato, provider);           
    var dataAlerta = dataInicio.AddMinutes(-minutos);

    Pero, de esta manera me aways tiene que establecer invariantculture a todos mis datetime. He encontrado el ajuste de la solución a mi cultura en la configuración de inicio.cs.

    Conjunto de la Cultura en el inicio.cs

     public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, CRMContext context)
    {
    loggerFactory.AddConsole(Configuration.GetSection("Logging"));
    loggerFactory.AddDebug();
    if (env.IsDevelopment())
    {
    app.UseDeveloperExceptionPage();
    app.UseDatabaseErrorPage();
    app.UseBrowserLink();
    }
    else
    {
    app.UseExceptionHandler("/Home/Error");
    }
    //Fixar Cultura para en-US
    RequestLocalizationOptions localizationOptions = new RequestLocalizationOptions
    {
    SupportedCultures = new List<CultureInfo> { new CultureInfo("en-US") },
    SupportedUICultures = new List<CultureInfo> { new CultureInfo("en-US") },
    DefaultRequestCulture = new RequestCulture("en-US")
    };
    app.UseRequestLocalization(localizationOptions);      
    app.UseStaticFiles();
    app.UseIdentity();
    //Add external authentication middleware below. To configure them please see https://go.microsoft.com/fwlink/?LinkID=532715
    app.UseMvc(routes =>
    {
    routes.MapRoute(
    name: "default",
    template: "{controller=Home}/{action=Index}/{id?}");
    });
    context.Database.EnsureCreated();
    }

    Espero que esta ayuda.

    OriginalEl autor Rogerio Azevedo

  7. 0

    Considerar el uso de una costumbre TypeConverter para su datetime (Fuente):

    using System;
    using System.ComponentModel;
    using System.Globalization;
    using System.Drawing;
    public class DeDateTimeConverter : TypeConverter {
    //Overrides the CanConvertFrom method of TypeConverter.
    //The ITypeDescriptorContext interface provides the context for the
    //conversion. Typically, this interface is used at design time to 
    //provide information about the design-time container.
    public override bool CanConvertFrom(ITypeDescriptorContext context, 
    Type sourceType) {
    if (sourceType == typeof(string)) {
    return true;
    }
    return base.CanConvertFrom(context, sourceType);
    }
    //Overrides the ConvertFrom method of TypeConverter.
    public override object ConvertFrom(ITypeDescriptorContext context, 
    CultureInfo culture, object value) {
    if (value is string) {
    if (DateTime.TryParse(((string)value), new CultureInfo("de-DE") /*or use culture*/, DateTimeStyles.None, out DateTime date))
    return date;
    }
    return base.ConvertFrom(context, culture, value);
    }
    }

    y uso TypeConverter atributo en su propiedad:

    [TypeConverter(typeof(DeDateTimeConverter))]
    public DateTime CustomDateTime { get; set; }

    Actualización

    Basado en mi experiencia y gracias a esta respuesta y @zdeněk comentario, TypeConverter atributo no funcionan y se debe registrar TypeConverter en Startup.cs:

    TypeDescriptor.AddAttributes(typeof(DateTime), new TypeConverterAttribute(typeof(DeDateTimeConverter)));

    OriginalEl autor Shahab

  8. -1

    Trate de configurar la cultura manualmente en su web.config

    <configuration>
    <system.web>    
    <globalization culture="de-DE" uiCulture="de-DE"/>
    </system.web>
    </configuration>

    EDIT: Ya me di cuenta de que esto es esencial, se puede hacer de esta manera en el Inicio.Configurar:

    var cultureInfo = new CultureInfo("de-DE");
    CultureInfo.DefaultThreadCurrentCulture = cultureInfo;
    CultureInfo.DefaultThreadCurrentUICulture = cultureInfo;
    La pregunta era acerca de Asp.NET Core
    Ya he probado la configuración de CultureInfo.DefaultThreadCurrentCulture y CultureInfo.DefaultThreadCurrentUICulture y en el inicio de la Prueba de la acción, que está correctamente ajustado en de-de. Pero ASP.NET core no importa, el parámetro GET se analiza mal.

    OriginalEl autor maksymiuk

  9. -3
    DateTime dt = DateTime.ParseExact(dateString, "ddMMyyyy", CultureInfo.InvariantCulture);
    dt.ToString("yyyyMMdd");

    Como por https://stackoverflow.com/a/3477821/2914174

    Sé que esto. Pero no ayuda a la causa aquí ASP.NET mismo Núcleo de analizar el parámetro GET a un objeto DateTime. Yo no hago el análisis. Sería una solución para el uso de una cadena en lugar de la fecha y hora como argumento de fecha y, a continuación, analizar como lo sugieren. Pero quiero evitar esta causa ASP.NET Núcleo de hacer un buen trabajo aquí, sólo con el formato incorrecto.
    ¿has probado mi respuesta ?

    OriginalEl autor Ryan

Dejar respuesta

Please enter your comment!
Please enter your name here