2009-09-16 24 views
6

He leído mucho sobre este problema, pero no puedo resolverlo.ASP.NET MVC DropDownList Valor seleccionado Problema

Tengo una lista desplegable en mi vista que se utiliza para paginación. Usted elige la página a la que desea ir y el formulario se envía. Cuando se devuelve la vista, se muestra la página solicitada. La lista desplegable cambia para reflejar la página que se muestra recientemente. Esto está funcionando bien.

Mi problema es este: Tengo 2 botones para enviar, uno para la página siguiente y el otro para la página anterior. En el controlador, si se ha presionado uno de los envíos, el número de página se debe incrementar o disminuir en 1. Esto está sucediendo y se está mostrando la página correcta de datos. Pero, la lista desplegable no, NO IMPORTA LO QUE HAGO, refleja el nuevo número de página cuando se muestra la vista.

Básicamente, si el menú desplegable es cambiado por el usuario, reflejará esos cambios cuando se envíe de vuelta después de un envío del formulario. Si cambio la página # programáticamente, el menú desplegable no cambiará, aunque se muestre la página correcta de datos.

Aquí es el método de acción:

public ActionResult Results(TechSearch search, string NextPage, string PrevPage) 
{ 
    if (NextPage != null) search.Page++; 
    if (PrevPage != null) search.Page--; 

    int resultCount = search.GetResultCount(Desk); 

    List<int> pages = new List<int>(); 
    int pageCount = (int)Math.Ceiling((decimal)resultCount/search.PageSize); 
    for (int i = 1; i <= pageCount; i++) pages.Add(i);   

    ViewData["pages"] = new SelectList(pages, search.Page);    
    ViewData["pageCount"] = pageCount; 

    return View(search); 
} 

Y aquí es la parte correspondiente de la vista:

<input type="submit" value="<" name="PrevPage" /> 
Page 
<%=Html.DropDownList("Page",(SelectList)ViewData["pages"]) %> 
of 
<%=ViewData["pageCount"]%> 
<input type="submit" value=">" name="NextPage" /> 

por favor ayuda.

EDITAR

Página 333 de Pro ASP.NET MVC Framework by Steven Sanderson:

Cómo controles de entrada y obtener sus valores

Cada uno de [los ayudantes HTML para Rendering controles de entrada] trata de poblar sí examinado para un valor en los siguientes lugares, en este orden de prioridad:

  1. ViewData.ModelState [ "ControlName"]. Value.RawValue parámetro
  2. valor pasado al método de ayuda HTML, o si usted ha llamado una sobrecarga que no incluya un parámetro de valor , entonces ViewData .Eval ("ControlName")

ModelState es un área de almacenamiento temporal que ASP.NET MVC utiliza para retener intentos de valores entrantes más vinculantes y validación de errores. Observe que está en la parte superior de la lista de prioridades, , por lo que sus valores anulan todo lo que podría establecer explícitamente. Esta convención significa que puede pasar un parámetro de valor explícito para actuar como el valor predeterminado o inicial de del ayudante; pero cuando reenvía la vista después de una falla de validación , el helper conservará el valor ingresado por el usuario en la preferencia a ese valor predeterminado.

He verificado que ViewData.ModelState ["Page"]. Value.RawValue contiene el número de página inesperado que me está molestando. ¿Cuál es la mejor manera de evitar esto?

+1

+1 Muy buen uso de las cadenas y el enlace del modelo para hacer un análisis legible cuyo botón de enviar se presionó. –

+0

@Dan - Gracias. Lo recogí de Pro ASP.NET MVC Framework por Steven Sanderson en la sección sobre Wizards and Multistep Forms (pg 396) –

+1

El libro de Steven Sanderson es muy bueno. – RichardOD

Respuesta

4

El problema era que ModelState sostenía la lista desplegable pasarle en valor. Para los controles de entrada HtmlHelper, a ModelState se le da prioridad sobre los valores explícitamente establecidos cuando se muestra un valor en el control de entrada.

Aquí es lo que he hecho en mi método de acción para solucionar el problema:

ModelState.Remove("Page"); 
return View(search); 

estoy interesado en escuchar otras maneras de fijar mi problema.

+1

Coloque el número de página directamente en el estado del modelo dentro de la acción en lugar de borrarlo. Su lista de selección se generaría fuera de la lista de páginas solamente. – Neal

0

Cambie el valor seleccionado con javascript al hacer clic en el botón siguiente o anterior, justo antes de su devolución de datos.

+0

Lo hice antes de hacer mi pregunta y eso me encargó, pero ¿por qué no funciona de otra manera? –

+0

El navegador está almacenando en caché la selección de usuarios. Al usar el javascript, está cambiando la selección de usuarios (y, por lo tanto, la impresión de la selección del navegador) antes de realizar la devolución de datos. La alternativa sería poner un valor en el encabezado de su página especificando que no hay almacenamiento en caché. Eso puede o no ser lo que necesita ... –

+0

El navegador no debe estar en caché. El método de formulario es un GET. Eso significa que el parámetro de la página se envía en la url, lo que hace que la url sea única. –

0
  1. ¿Estás seguro de que se le garantiza que al menos uno de NextPage o PrevPage será nula? (Y usted no recibe nada extraño como String.Empty forzar a un incremento y decremento?)
  2. Podría .LastOrDefault() ser reemplazado con sólo .Last() y que está seguro de que no está asignando default(int)-search.Page?
+0

1.) Sí, estoy seguro. 2.) Esa línea de código no es relevante para el problema. –

0

¿Tiene los siguientes algún efecto?

ViewData["pages"] = new SelectList(pages, 
            pages.FirstOrDefault(p => p == search.Page)); 

Sustitución

ViewData["pages"] = new SelectList(pages, search.Page); 
+0

Eso no tuvo ningún efecto. –

Cuestiones relacionadas