6

Vedo che ci sono alcune domande simili a questo, ma nessuno risolve il mio problema.Convalida MVC3 con ComponentModel.DataAnnotazioni per il formato data britannico (anche utilizzando jquery ui datepicker)

Sto lavorando a un'app MVC3 con Entity Framework 4.3. Ho un campo di date nel Regno Unito che ho intenzione di consentire all'utente di modificare utilizzando il Datepicker dell'interfaccia utente di Jquery (che ho lavorato grazie a this blog).

Fortunatamente per me questo blog include istruzioni su come rendere il datapicker usando il formato UK, tuttavia la convalida EF mi sta ancora dicendo che devo inserire un formato di data valido. Per quanto non mi impedisca di inviare la data al DB, è solo la convalida non invadente che avvia e mostra il messaggio.

Al momento ho la seguente annotazione di dati:

[DataType(DataType.Date)] 
public System.DateTime Module_Date { get; set; } 

ma ho anche provato ad aggiungere:

[DisplayFormat(DataFormatString="{0:dd/MM/yyyy}")] 

che ha avuto alcun effetto. Spero che qualcuno abbia una soluzione perché non mi piace disattivare la convalida non invadente per fermare questo messaggio di errore.

Grazie

EDIT

seguenti risposta @Iridio, ho guardato in aggiunta di un modello vincolante, e in effetti dai pochi posti come questo che ho letto sembrava essere la cosa giusta da fare , ma quello che ho trovato non ha alcun effetto. Ecco quello che ho provato:

public class DateTimeBinder : IModelBinder 
{ 
    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) 
    { 
     var value = bindingContext.ValueProvider.GetValue(bindingContext.ModelName); 
     var date = value.ConvertTo(typeof(DateTime), CultureInfo.CurrentCulture); 

     return date; 
    } 
} 

con questo nel metodo del file Global.asax.csApplication_Start():

ModelBinders.Binders.Add(typeof(DateTime), new DateTimeBinder()); 
ModelBinders.Binders.Add(typeof(DateTime?), new DateTimeBinder()); 
+0

Credo che si riferisca alle note System.ComponentModel.DataAnnotation piuttosto che alle annotazioni dei dati EntityFramework? Se hai seguito il blog, allora specifichi il formato dei dati '{dateFormat:" gg/mm/aa "}' nel tuo script lato client? In tal caso, quale versione dello script ui jquery stai usando? – Dangerous

+0

oooh hai ragione, sto usando i modelli ComponentModel. Mi sono abituato a usare gli EF sull'ultimo progetto. aggiornerà. Stavo usando jquery ui 1.8.7 ma ho aggiornato al più tardi secondo la tua risposta qui sotto senza alcun risultato – Ben

+0

oh e sì ho specificato '{dateFormat:" gg/mm/aaaa "}' – Ben

risposta

4

Giusto, il problema era con gli script validazione jquery che insistevano sull'uso del datafomat statunitense. Mi limiterò a dare il giusto tono al fatto che la maggior parte del mondo usa dd/mm/yyyy però.

In ogni caso, alla fine ho trovato la risposta alle mie disgrazie in un commento ad una risposta di un simile question, il cui autore gentilmente ha scritto un blog post di come ha risolto il problema.

Fondamentalmente ho utilizzato lo jquery globalize script e ho impostato la cultura su en-GB. Devo dire che nel suo blog che non menziona dove mettere il pezzo in cui si specifica la cultura, quindi ho solo spinto in nei tag script nella pagina sotto i riferimenti agli script di globalizzazione:

<script src="@Url.Content("~/Scripts/globalize.js")" type="text/javascript"></script> 
<script src="@Url.Content("~/Scripts/globalize.culture.en-GB.js")" type="text/javascript"></script> 
<script type="text/javascript"> 
    Globalize.culture("en-GB"); 
    $.validator.methods.date = function (value, element) { 
     return this.optional(element) || Globalize.parseDate(value); 
    }; 
</script> 
+0

In realtà non dovrebbe essere necessario andare a tutti questi problemi solo per rendere valida la data del Regno Unito !! Ma grazie per le informazioni sono rimasto bloccato su questo. Spero solo che jQuery aggiunga un modo più elegante per farlo presto. Quel file globalize.js (ironicamente scritto con z :)) è abbastanza grande. –

+0

@PaulJohnson Sono d'accordo, non dovrei farlo, e infatti non è una buona soluzione per un sacco di casi perché impone sempre date in formato UK. – Ben

+0

Ho cercato per due giorni una soluzione a questo problema, con il dito che puntava a JQuery per i motivi che hai menzionato. Questa correzione ha funzionato perfettamente per me, anche se il modo più semplice per implementarlo era usare nuget per aggiungere il pacchetto jquery-globalize e, se lo fai, le posizioni degli script diventano /Scripts/globalize/globalize.js e/Scripts/globalize/culture/globalize.culture.en-GB.js –

1

si deve scrivere si possiede ModelBinder per il tipo DateTime.

Questo è un raccoglitore che ho scritto per un problema simile ma con un tipo decimale (forse ne avrete bisogno). si dovrebbe cogliere l'idea e adattarlo alle proprie necessità

public class DecimalModelBinder : IModelBinder 
{ 
    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) 
    { 
    ValueProviderResult valueResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName); 
    ModelState modelState = new ModelState { Value = valueResult }; 
    object actualValue = null; 
    try 
    { 
     actualValue = Convert.ToDecimal(valueResult.AttemptedValue, CultureInfo.CurrentCulture); 
    } 
    catch (FormatException e) 
    { 
     modelState.Errors.Add(e); 
    } 

    bindingContext.ModelState.Add(bindingContext.ModelName, modelState); 
    return actualValue; 
    } 
} 

Poi nel Global.asax si registra il legante e il gioco è fatto

protected void Application_Start() 
{ 
    AreaRegistration.RegisterAllAreas(); 
    RegisterGlobalFilters(GlobalFilters.Filters); 
    RegisterRoutes(RouteTable.Routes); 
    //Here you tell how to hendle the specific type 
    ModelBinders.Binders.Add(typeof(decimal), new DecimalModelBinder()); 
} 

UPDATE

Dopo il chiarimento this answer dovrebbe aiutare

+0

wow risposta rapida! Grazie! Cercherò di risolvere questo problema con – Ben

+0

, ma non posso farlo funzionare, ho aggiornato la mia domanda con il mio tentativo – Ben

+0

Aggiornato la risposta per usare globalize nella validazione lato client – Iridio

1

Credo che ci sia un bug nella versione di script della data di jquery ui picker fornito con il framework mvc3 (jquery-ui-1.8.11.js).

Se si specifica la data nel formato Regno Unito (come del resto gli stati del blog):

$(document).ready(function() { 
    $('.date').datepicker({dateFormat: "dd/mm/yy"}); 
}); 

poi jquery-ui-1.8.11.js sembra avere un problema con la convalida della data e continua a chiedere per una data valida per il Regno Unito (ma la validazione appare casuale).Se cambi il formato della data in "mm/gg/aa", questo problema andrà via ma non va bene per le date inglesi.

Il problema è stato risolto in una versione successiva di quella libreria in modo da scaricare la versione più recente (credo 1.8.18 al momento della scrittura) o fare riferimento alla CDN:

<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.18/jquery-ui.min.js" type="text/javascript"></script> 
+0

sembra che io stia usando una versione leggermente più vecchia (1.8.7) così scambiato in quello nuovo, e non ha fatto differenza. grazie però – Ben

0

Ho avuto questo problema proprio ora, mi ci sono voluti ore per rintracciare il motivo. Non sto dicendo che questo è il tuo problema ma dopo aver passato ore a cambiare la globalizzazione su tutto, ecc. Ho pensato di postare il problema qui per tutte le persone che lottano come me.

In ogni caso, il problema nel mio progetto non era in realtà quello che pensavo. Avevo decorato la proprietà con [DataAnnotationsExtentions.Date] che, si scopre, mucks up la convalida del lato client in chrome quando si tratta della localizzazione (cioè se si desidera un giorno dopo il 12 in Inghilterra) anche se sembra funzionare bene in altri browser. Appena ho rimosso che funzionava

1

realtà ho trovato una soluzione migliore qui .... da #fretje

Override jquery date

ho modificato la sua/il suo codice di un po 'anche se in modo che possa ancora prendere formati di data 30 maggio 2012 come di seguito.

$(function() { 
    $.validator.addMethod(
     "date", 
     function (value, element) { 

      //Added to validate dates like 31 May 2012 
      if (value.split('/').length === 1) 
       return this.optional(element) || !/Invalid|NaN/.test(new Date(value)); 

      var bits = value.match(/([0-9]+)/gi), str; 
      if (!bits) 
       return this.optional(element) || false; 
      str = bits[1] + '/' + bits[0] + '/' + bits[2]; 
      return this.optional(element) || !/Invalid|NaN/.test(new Date(str)); 
     }, 
     "Please enter a date in the format dd/mm/yyyy" 
    ); 

    $global.init(); 
}); 
0

Il problema è che per qualche motivo se si mette una classe denominata "data" nella vostra casella di testo, Chrome basta avere folle come potrebbe descriverli qui a this blog. Ho avuto lo stesso problema e ho appena cambiato il nome della classe in customDate ed è stato risolto.

+0

Si prega di non pubblicare solo risposte di collegamento –

Problemi correlati