2011-10-14 7 views
12

Necesito crear un enlace que se basará en mis criterios de búsqueda. Por ejemplo:¿Puedo pasar un enlace de ver modelo a acción para generar una ruta?

localhost/Search?page=2&Location.PostCode=XX&Location.Country=UK&IsEnabled=true 

parámetros de este enlace son los valores de las propiedades en mi SearchViewModel.

Idealmente me gustaría tener algo en la línea de:

@Html.ActionLink("Search","User", Model.SearchCriteria) 

Es esto apoyado por defecto o tengo que pasar propiedades de mi modelo de vista en un objeto de tipo RouteValueDictionary y luego usar eso?

Mi objetivo es escribir un ayudante de paginación que genere números de página y agregue los parámetros de los criterios de búsqueda a los enlaces generados.

E.g.

@Html.GeneratePageLinks(Model.PagingInfo, x => Url.Action("Index"), Model.SearchCriteria) 

He combinado sus soluciones con la sugerencia de PRO libro de ASP.NET MVC 3 y terminó con lo siguiente:

ayudante para generar enlaces. Lo interesante es el parámetro pageUrlDelegate que luego se utiliza para invocar Url.Action para los enlaces que generan:

public static MvcHtmlString PageLinks(this HtmlHelper html, PagingInfoViewModel pagingInfo, 
             Func<int,String> pageUrlDelegate) 
{ 
    StringBuilder result = new StringBuilder(); 
    for (int i = 1; i <= 5; i++) 
    { 
     TagBuilder tagBuilder = new TagBuilder("a");         
     tagBuilder.MergeAttribute("href", pageUrlDelegate(i)); 
     tagBuilder.InnerHtml = i.ToString(); 
     result.Append(tagBuilder.ToString());    
    }    

    return MvcHtmlString.Create(result.ToString()); 
} 

Luego, en el modelo de vista:

@Html.PageLinks(Model.PagingInfo, x => Url.Action("Index","Search", new RouteValueDictionary() 
    { 
      { "Page", x }, 
      { "Criteria.Location.PostCode", Model.Criteria.Location.PostCode }, 
      { "Criteria.Location.Town", Model.Criteria.Location.Town}, 
      { "Criteria.Location.County", Model.Criteria.Location.County} 
    })) 
) 

Todavía no estoy feliz con los nombres de propiedades de cadenas, pero tendrá que hacer por ahora.

Gracias :)

Respuesta

10

Idealmente me gustaría tener algo en la línea de:

@Html.ActionLink("Search","User", Model.SearchCriteria)

Desafortunadamente eso no es posible. Deberá pasar propiedades una a una. Se podría de hecho utilizar la sobrecarga que tiene un RouteValueDictionary:

@Html.ActionLink(
    "Search", 
    "User", 
    new RouteValueDictionary(new Dictionary<string, object> 
    { 
     { "Location.PostCode", Model.SearchCriteria.PostCode }, 
     { "Location.Country", Model.SearchCriteria.Country }, 
     { "IsEnabled", Model.IsEnabled }, 
    }) 
) 

Por supuesto que es probablemente mejor para escribir un ayudante ActionLink costumbre de hacer esto:

public static class HtmlExtensions 
{ 
    public static IHtmlString GeneratePageLink(this HtmlHelper<MyViewModel> htmlHelper, string linkText, string action) 
    { 
     var model = htmlHelper.ViewData.Model; 
     var values = new RouteValueDictionary(new Dictionary<string, object> 
     { 
      { "Location.PostCode", model.SearchCriteria.PostCode }, 
      { "Location.Country", model.SearchCriteria.Country }, 
      { "IsEnabled", model.IsEnabled }, 
     }); 
     return htmlHelper.ActionLink(linkText, action, values); 
    } 
} 

y luego:

@Html.GeneratePageLink("some page link text", "index") 

Otra posibilidad es pasar solo el id y hacer que la acción del controlador obtenga el modelo y los valores correspondientes desde donde lo haya buscado inicialmente en el control acción de carga que rindió esta vista.

+0

Hola Darin, gracias por su respuesta. Probablemente usaré tu segundo consejo y crearé un ayudante para generar enlaces de página. –

+0

Consulte la edición –

1

Aquí hay algunos códigos tomados del Tekpub samples de Steve Sanderson que es lo que está buscando.En primer lugar definir un método de extensión de su objeto -

public static RouteValueDictionary DetailsRouteValues(this JobAd jobAd) 
{ 
    return new RouteValueDictionary 
    { 
     { "controller", "Jobs" }, 
     { "action", "Details" }, 
     { "id", jobAd.JobAdId }, 
     { "country", MakeSimpleUrlSegment(jobAd.LocationCountry) }, 
     { "city", MakeSimpleUrlSegment(jobAd.LocationCity) }, 
     { "title", MakeSimpleUrlSegment(jobAd.Title) } 
    }; 
} 

luego llamar a Html.RouteLink utilizando ese método -

<%= Html.RouteLink(ad.Title, ad.DetailsRouteValues())%> 
+0

Hola, gracias por una solución alternativa. Necesito decidir si es correcto ampliar mis criterios de búsqueda con un método para devolver los valores de ruta. Me gusta mantener mis modelos de vista lite. –

Cuestiones relacionadas