27 messaggi dal 17 maggio 2011
Ciao,

avrei un problema che non saprei come risolvere.
Su una maschera devo filtrare i dati in base ad un intervallo di date.
Testando la cosa nel mio ambiente di sviluppo il filtro viene eseguito correttamente, mentre provando direttamente nell'ambiente di produzione installato nel server viene sollevata questa eccezione:

500 - Internal server error.
There is a problem with the resource you are looking for, and it cannot be displayed.

Le date su cui ho filtrato i dati sono dal 01/06/2017 al 30/06/2017.
A mio avviso nel server di produzione le date vengono valutate nel formato MM/dd/yyyy, anche se nel Model ho impostato tutte le date con questa annotation: [DisplayFormat(DataFormatString = "{0:dd/MM/yyyy}", ApplyFormatInEditMode = true)].

Per sicurezza ho provato a collegarmi al database di produzione con Visual Studio ed eseguire la stessa ricerca e anche in questo caso la ricerca è stata eseguita con successo.
Quindi credo sia qualcosa legato al server.

Riuscite ad indicarmi come avere lo stesso comportamento sia in fase di sviluppo sia in produzione?

Grazie
Ciao
Enrico
11.886 messaggi dal 09 febbraio 2002
Contributi
Ciao Enrico,
prova a scriverti un model binder personalizzato per il tipo DateTime, così che tu abbia il controllo preciso sul come va parsata la data. Leggi qui, ne abbiamo parlato un po'.

http://forum.aspitalia.com/forum/post/416160/DateTime-MVC-Inverte-Giornimesi.aspx?PageIndex=1

Può sembrare una soluzione eccessiva per un problema così semplice ma almeno ti dà garanzia di successo.

ciao,
Moreno

Enjoy learning and just keep making
27 messaggi dal 17 maggio 2011
Ciao,

scusami ma proprio non riesco a farlo funzionare.
Ho aggiunto queste classi per eseguire il bind:

public class CustomBinder
    {
        static string IT_CULTURE = "it-IT";

        public class DateTimeBinder : IModelBinder
        {
            public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
            {
                var value = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
                bindingContext.ModelState.SetModelValue(bindingContext.ModelName, value);

                return value.ConvertTo(typeof(DateTime), CultureInfo.GetCultureInfo(IT_CULTURE));
            }
        }

        public class NullableDateTimeBinder : IModelBinder
        {
            public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
            {
                var value = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
                bindingContext.ModelState.SetModelValue(bindingContext.ModelName, value);

                return value == null
                    ? null
                    : value.ConvertTo(typeof(DateTime), CultureInfo.GetCultureInfo(IT_CULTURE));
            }
        }
    }


Poi ho aggiunto questo all'interno del metodo Application_Start() di Global.asax.cs:

ModelBinders.Binders.Add(typeof(DateTime), new CustomBinder.DateTimeBinder());
ModelBinders.Binders.Add(typeof(DateTime?), new CustomBinder.NullableDateTimeBinder());


In debug vedo che ci entra quando valuta la entity, però in produzione il messaggio visualizzato è sempre lo stesso.
Sbaglio qualcosa?

Enrico
27 messaggi dal 17 maggio 2011
Ho modificato il binder in questo modo:

public class DateTimeBinder : IModelBinder
        {
            public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
            {
                var value = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
                bindingContext.ModelState.SetModelValue(bindingContext.ModelName, value);

                DateTime date = DateTime.ParseExact(value.AttemptedValue.Substring(0, 10), "dd/MM/yyyy", null);
                return date;
            }
        }


Ed ho attivato gli errori di ASP.NET nel server di produzione.
Il messaggio che viene restituito è:

Server Error in '/' Application.

String was not recognized as a valid DateTime.

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.FormatException: String was not recognized as a valid DateTime.

Source Error:

An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.

Stack Trace:


[FormatException: String was not recognized as a valid DateTime.]
System.DateTimeParse.ParseExact(String s, String format, DateTimeFormatInfo dtfi, DateTimeStyles style) +4327446
System.DateTime.ParseExact(String s, String format, IFormatProvider provider) +31
DateTimeBinder.BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) in CustomBinder.cs:28


La riga 28 di CustomBinder è questa:
DateTime date = DateTime.ParseExact(value.AttemptedValue.Substring(0, 10), "dd/MM/yyyy", null);
Modificato da stone87 il 28 giugno 2017 10.01 -
11.886 messaggi dal 09 febbraio 2002
Contributi
Ciao,
logga su disco il valore di value.AttemptedValue. Potrebbe contenere un valore inatteso.
Puoi anche avere qualche indizio andando a guardare cosa il client invia al server dagli strumenti di sviluppo del browser (tasto F12) e ispezionando le richieste dalla scheda "Rete" o "Network".

ciao,
Moreno

Enjoy learning and just keep making
27 messaggi dal 17 maggio 2011
Ho loggato il valore restituito in POST.
Ad esempio per la giornata di ieri il valore era 6/28/2017.
Ho risolto modificando il binder custom in questo modo, però non è che mi piaccia molto:

if (!string.IsNullOrEmpty(displayFormat) && value != null)
            {
                DateTime date;
                displayFormat = displayFormat.Replace("{0:", string.Empty).Replace("}", string.Empty);
                int stringLength = value.IndexOf(" ") > 0 ? value.IndexOf(" ") : value.Length;
                var valueToString = value.Substring(0, stringLength);
                // use the format specified in the DisplayFormat attribute to parse the date
                if (DateTime.TryParseExact(valueToString, displayFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out date))
                {
                    return date;
                }
                else
                {
                    var dateDay = valueToString.Substring(valueToString.IndexOf("/") + 1, valueToString.LastIndexOf("/") - valueToString.IndexOf("/") - 1).PadLeft(2, '0');
                    var dateMonth = valueToString.Substring(0, valueToString.IndexOf("/")).PadLeft(2, '0');
                    var dateYear = valueToString.Substring(valueToString.LastIndexOf("/") + 1, valueToString.Length - valueToString.LastIndexOf("/") - 1);
                    valueToString = dateDay + "/" + dateMonth + "/" + dateYear;
                    if (DateTime.TryParseExact(valueToString, displayFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out date))
                    {
                        return date;
                    }
                }
            }


Ciao
Enrico
11.886 messaggi dal 09 febbraio 2002
Contributi
Ciao Enrico,
ok, il problema è che il mese non è composto di 2 cifre e, inoltre, è invertito con il giorno, il che non lo rende adeguato al formato italiano dd/MM/yyyy.

Potresti risolvere la situazione lato client, facendo in modo che il date picker che stai usando componga la data sempre nello stesso formato, a prescindere dalle impostazioni della lingua del client.

ciao,
Moreno

Enjoy learning and just keep making
27 messaggi dal 17 maggio 2011
Lato client il dato è visualizzato correttamente, infatti ho modificato il date picker che compone le date.

Il problema è lato server in questo caso.
Con il mio binder sono riuscito a risolvere, però volevo trovare una soluzione più elegante.

Ciao
Enrico

Torna al forum | Feed RSS

ASPItalia.com non è responsabile per il contenuto dei messaggi presenti su questo servizio, non avendo nessun controllo sui messaggi postati nei propri forum, che rappresentano l'espressione del pensiero degli autori.