2010-01-07 5 views
5

ich mit einem DateTime- Suchkriterium ein Suchformular habe, sowie einige anderen Kriterien:eine Action mit einem Datetime in dem Query-String in ASP.NET MVC erstellen

<form method="get" action="/app/search"> 
    <input type="text" value="13/01/2010" name="BeginDate"/> 
    <input type="text" value="blah" name="SomeOtherCriterion"/> 
<form> 

So habe ich einen Search-Controller mit einem Standard Aktion (nennen wir es Index) und mit einem SearchCriteria-Parameter.

public class SearchController 
{ 
    public ActionResult Index(SearchCriteria searchCriteria) {//blah } 
}  

public class SearchCriteria 
{ 
    public DateTime BeginDate {get; set;} 
    public string SomeOtherCriterion {get; set;} 
} 

Nun, wenn ich eine Action, vorbei in einem such Wert erstellt werden soll, also:

Html.ActionLink("Search", "Index", searchCriteria) 

Ich erhalte die Begindate Abfrage-String-Parameter in US-Format. Wenn man auf Google schaut und in System.Web.Routing mit Reflector herumstochert, scheint es so zu sein, weil es die InvariantCulture verwendet, also kann ich nichts dagegen tun.

Es scheint, als ob niemand diese Frage schon einmal gestellt hat, also denke ich, dass ich etwas sehr dummes mache ... Bitte helfen Sie!

EDIT: Pass in SearchCriteria zu ActionLink anstelle von anonymen Objekt, um zu zeigen, warum ich nicht einfach die benutzerdefinierte ToString() selbst tun kann.

Antwort

3

Angesichts der Tatsache, dass das Framework hart codiert zu sein scheint, um dieses Datenelement mit InvariantCulture zu behandeln, glaube ich nicht, dass Sie viel tun können, um es transparent zu machen.

Es ist eine hässliche Option - laden Sie die MVC Quelle und reißen den Code für alle problematischen Klassen aus Route bis ParsedRoute Ihre eigene RouteBase Implementierung zu erstellen, das tut, was Sie brauchen.

Wenn ich absolut hatte, um die DateTime-Deklaration auf der SearchCriteria Klasse zu halten, dann ist das die Route (Entschuldigung für das Wortspiel), die ich wählen würde.

jedoch eine weitaus einfachere Lösung wäre Ihre such Klasse zu ändern, um eine etwas andere Erklärung für das Datetime-Feld zu verwenden, basierend auf einem Typ wie folgt aus:

public class MyDateTime 
{ 
    public DateTime Value { get; set; } 
    //for passing MyDateTime in place of a DateTime without casting 
    public static implicit operator DateTime(MyDateTime instance) { return instance.Value; } 
    //so you can assign a MyDateTime from a DateTime without a cast 
    //- e.g. MyDateTime dt = DateTime.Now 
    public static implicit operator MyDateTime(DateTime instance) { return new MyDateTime() { Value = instance }; } 
    //override ToString so that CultureInfo.CurrentCulture is used correctly. 
    public override string ToString() 
    { 
    return Value.ToString(CultureInfo.CurrentUICulture); 
    } 
} 

In der Theorie sollten Sie in der Lage sein zu rollen diese Änderung ohne viel Aufhebens aus.

Die große Arbeit, wenn Sie eine Menge Code, die Mitglieder haben könnte (zB .Days etc) der Datetime-Instanz in such verwendet: Sie haben entweder die Mitglieder auf MyDateTime, Umwickeln des inneren DateTime Value oder alle zu reproduzieren ändern der zu verwendende Code .Value.Member.

+0

Nicht wirklich praktisch für uns, aber auf jeden Fall die innovativste Lösung, so werde ich es akzeptieren. Danke Zoltan. – Gaz

1

Können Sie in Ihrem ActionLink ein formatiertes Datum angeben? Versuchen Sie folgendes:

Html.ActionLink("Search", 
       "Index", 
       new {BeginDate = 
         DateTime.Now.ToString("d", new CultureInfo("pt-BR");}) 

Natürlich ändert dies Begindate in einen String statt eines Datetime ... aber vielleicht ist das für Sie arbeiten?

+0

Siehe Bearbeiten. Ich möchte in der Lage sein, einen SearchCriteria gerade herein zu geben, anstatt ein anonymes Objekt zu verwenden. Ich wusste, dass ich etwas von der Frage vermisste! – Gaz

+0

Ah, das ist ein bisschen härter. Ich denke du könntest den SearchCriteria immer anonymisieren, nur um die Datums-Zeichenkette zu formatieren, aber das wäre ein großer Schmerz ... – womp

+0

Jemand der dich runterwog womp. Schätze, es ist dir egal, mit 23000 Punkten, aber es schien trotzdem hart. Ich habe zur Kompensation geupdated. – Gaz

1

Wir verwenden dafür das Format ISO ("s" in einem Formatstring - JJJJ-MM-DDTHH: MM: SS). Es funktioniert korrekt und JavaScript kann auch damit umgehen.

+1

Aber wie erhalten Sie ActionLink oder eine der anderen MVC-Methoden, die ein RouteValueDictionary verwenden, um ein DateTime in dieses Format zu konvertieren? – Gaz

+0

Einfach als String einfügen: 'new RouteValueDictionary (neu {SomeDate = anotherDate.ToString (" s ")})' –

1

Vielleicht könnten Sie ein Model Binder verwenden, um das Datum zu formatieren und zu analysieren? Lies einfach den Artikel noch einmal und merkte, dass er das Datum nicht formatiert ... Wahrscheinlich wird es nicht funktionieren. Ich werde die Antwort hinterlassen, obwohl im Falle bietet es eine unbeabsichtigte Inspiration :)

+0

Danke Chris. AFAIK, das nur für die Bearbeitung von Anfragen geeignet ist, hilft beim Erstellen einer URL mit ActionLink nicht. – Gaz

+0

Kommentiert zur gleichen Zeit, die ich bearbeitet habe :) –

1
poking around in System.Web.Routing using Reflector it 

scheint zu sein, weil es die InvariantCulture verwendet

Sind Sie wirklich über diese shure? Die Teile von Modelbinding und UrlBuilding, die ich überprüft habe, verwendeten CurrentCulture. Können Sie überprüfen, was passiert, wenn Sie CurrentCulture vor dem Rendern des Links einstellen?

+0

Das Bit, das ich sehe, ist System.Web.Routing.ParsedRoute.Bind. Unten am unteren Rand, wo "unbenutzte Werte" in die Abfragezeichenfolge eingefügt werden. (Obwohl jeder ToString in dieser Methode InvariantCulture verwendet.) Ich habe versucht, CurrentCulture zu setzen. Es hilft nicht. – Gaz

2

Um Probleme im Zusammenhang mit regionalen Einstellungen und "Kultur" zu vermeiden, behandle ich Datum und Uhrzeit als separate ungebundene Felder und dann sie in DateTime in meinem Controller zusammen.

Beispiel:

Year [ ] Month [ ] Day [ ]

ich immer präsent getrennte Textfelder für Jahr, Monat und Tag, in dieser Reihenfolge, so dass es keine Verwirrung zwischen US-Format sein kann (Monat/Tag/Jahr) und mehr oder weniger der Rest des Weltformats (Tag/Monat/Jahr).

1

Holen Sie sich das ASP.NET MVC 1.0 Buch geschrieben von Scott Hanselman, Scott Guthrie, Phil Haack und Rob Conery. Sie tun genau dieses Szenario in dem Buch. Sie verwenden eine bestimmte Route. Ich sehe es gerade auf Seite 216 an.

Sie tun es, indem Tag, Monat und Jahr auseinander brechen. Dann liegt es in Ihrer Verantwortung, diese Werte so zu verwenden, wie sie zurückkommen.