2010-01-07 14 views
5

tengo un formulario de búsqueda con un criterio de búsqueda DateTime, además de algunos otros criterios:Creación de un ActionLink con un DateTime en la cadena de consulta en ASP.NET MVC

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

Así que tener un controlador de búsqueda con un valor predeterminado Acción (llamémoslo índice) y con un parámetro SearchCriteria.

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

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

Ahora si quiero crear una ActionLink, pasando de un valor searchCriteria, por lo tanto:

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

me sale el parámetro de cadena de consulta en formato BeginDate Estados Unidos. Buscar en Google y hurgar en System.Web.Routing usando Reflector parece ser porque usa InvariantCulture, por lo que no hay nada que pueda hacer al respecto.

Parece que nadie ha hecho esta pregunta antes, así que supongo que estoy haciendo algo muy estúpido ... ¡Por favor ayuda!

EDITAR: Pase en SearchCriteria a ActionLink en lugar de a un objeto anónimo para mostrar por qué no puedo hacer el personalizado ToString().

Respuesta

3

Dado que el marco parece estar codificado para manejar este dato usando InvariantCulture, no creo que haya mucho que pueda hacer para que funcione de forma transparente.

Hay una opción fea - descargar el código fuente MVC y arrancar el código para todas las clases de ofender Route a ParsedRoute para crear su propia RouteBase aplicación que hace lo que necesita.

Si tengo absolutamente tenía para mantener la declaración de fecha y hora en la clase SearchCriteria, entonces esa es la ruta (lo siento por el juego de palabras) que elegiría.

Sin embargo, una solución mucho más fácil sería cambiar la clase searchCriteria utilizar una declaración ligeramente diferente para el campo DateTime, basado en un tipo como éste:

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); 
    } 
} 

En teoría debería ser capaz de rodar este cambio sin demasiado alboroto.

La gran trabajo podría ser si usted tiene una gran cantidad de código que utiliza miembros (por ejemplo .Days etc) de la instancia de DateTime en searchCriteria: o se tiene que reproducir aquellos miembros de MyDateTime, envolviendo todo el interior DateTime Value o cambia todo el código para usar .Value.Member.

+0

No es realmente práctico para nosotros, pero definitivamente es la solución más ingeniosa, así que lo aceptaré. Gracias Zoltan. – Gaz

1

¿Puede proporcionar una fecha formateada en su ActionLink? Prueba esto:

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

Por supuesto, esto cambia BeginDate a una cadena en lugar de un DateTime ... pero tal vez eso va a funcionar para usted?

+0

Ver la edición. Quiero poder pasar un SearchCriteria directamente en lugar de usar un objeto anónimo. ¡Sabía que me faltaba algo de la pregunta! – Gaz

+0

Ah, eso es un poco más difícil. Supongo que siempre se puede anonimizar SearchCriteria solo para formatear la cadena de fecha, pero eso sería un gran dolor ... – womp

+0

Alguien votó negativamente por ti. Supongo que no te importa con 23000 puntos, pero de todos modos parecía duro. Subí para compensar. – Gaz

1

Utilizamos el formato ISO ("s" en una cadena de formato - YYYY-MM-DDTHH: MM: SS) para esto. Funciona correctamente, y JavaScript también puede manejarlo.

+1

¿Pero cómo obtienes ActionLink o cualquiera de los otros métodos MVC que usan un RouteValueDictionary para convertir un DateTime a este formato? – Gaz

+0

Simplemente colóquelo como una cadena: 'nuevo RouteValueDictionary (nuevo {SomeDate = anotherDate.ToString (" s ")}}' –

1

¿Quizás podría usar un Model Binder para formatear y analizar la fecha? Solo volvió a leer el artículo y notó que no formatea la fecha ... Probablemente no funcionará. Voy a dejar la respuesta, aunque en caso de que proporciona ninguna inspiración involuntaria :)

+0

Gracias Chris. AFAIK, que solo sirve para gestionar las solicitudes recibidas, no ayuda a crear una URL con ActionLink. – Gaz

+0

Comentada al mismo tiempo que estaba editando :) –

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

parece ser debido a que utiliza la InvariantCulture

¿Está realmente Shure de esto? Las partes de Modelbinding y UrlBuilding que verifiqué usaron CurrentCulture. ¿Puedes verificar qué sucede si configuras CurrentCulture antes de renderizar el enlace?

+0

El bit que estoy viendo es System.Web.Routing.ParsedRoute.Bind. Abajo en la parte inferior donde pone cualquier "valor no utilizado" en la cadena de consulta. (Aunque cada ToString en este método utiliza InvariantCulture). He intentado configurar CurrentCulture. No ayuda. – Gaz

2

Para evitar problemas relacionados con la configuración regional y "Cultura", Trato la fecha y la hora como campos independientes y luego los ensambla en DateTime en mi Controlador.

Ejemplo:

Year [ ] Month [ ] Day [ ]

siempre presentes cuadros de texto separados para el año, mes y día, en ese orden por lo que no puede haber ninguna confusión entre el formato de los Estados Unidos (mes/día/año) y más o menos el resto del formato del mundo (día/mes/año).

1

Obtenga el libro ASP.NET MVC 1.0 escrito por Scott Hanselman, Scott Guthrie, Phil Haack y Rob Conery. De hecho, hacen este escenario exacto en el libro. Usan una ruta específica. Lo estoy viendo en este momento en la página 216.

Lo hacen por romper día, mes y año. Entonces es su responsabilidad usar esos valores a medida que vuelven.

Cuestiones relacionadas