Question

I inherited a grid that is filtered by search terms. The person who built it added the search terms to the model to make them easier to pass throughout the process. When the search terms were a simple string everything seemed to work fine, but to refactor it into a List<> to account for multiple search terms. On the view page "searchterms" displays at it should, but when it gets to the controller, it's no longer the proper value(s), it displays as "System.Collections.Generic.List`1[System.String]", not the values, which then gums up the rest of the process. From there I try to filter a list by the search terms using Linq I got from SO. Please advise if you can and thanks in advance.

The View:

  <%              
var filePath = Model.FullPath;
var searchterms = new List<string>();
searchterms = Model.SearchTrms;

Html.Telerik().Grid<FileModel>()
    .Name("DocumentsGrid")
    .DataKeys(key => key.Add(x => x.FullPath))
    .Columns(columns =>
    {
        columns.Bound(x => x.FullPath).Format("<input type='checkbox'  value='{0}'>").Encoded(false).Width(22).Title("");
        ...

    })
    .DataBinding(dataBinding => dataBinding.Ajax()
                .Select("MyGridAction", "MyController", new { filePath  , searchterms })
                )
    ...
    .Render();
%>

the Model:

  public class FileModel
{
       ...

    public string FullName { get; private set; }
       ...
    public string Description { get;   set; }

    public List<string> SearchTrms  { get;   set; }

    public IList<FileModel> SubFolders { get; set; }
       ...

}

the Controller:

    [GridAction]
    public ActionResult MyGridAction(string filePath, List<string> searchterms)
    {
      ...

  dbfiles = GetFiles(userName, searchterms);

      ...

}



   public List<File> GetFiles(string userName, List<string> searchterms)
    {
        using (DBEntities ode = new DBEntities())
        {
            ode.ContextOptions.LazyLoadingEnabled = false;
            List<File> fileset1 = (from p in ode.aspnet_Users
                                   from q in p.Files
                                   where p.UserName == userName
                                   select q).ToList<File>();


            List<File> filteredlist = (from f in fileset1
                                       from s in searchterms
                                       where f.Name.Contains(s)
                                       select f).ToList<File>();

            return filteredlist;
        }
    }

I'll be happy to post more info if needed.

Était-ce utile?

La solution

The reason why you're seeing "System.Collections.Generic.List'1[System.String]" is because this is what listOfStrings.ToString() returns. Which is what is being called when you populate your route values by using the anonymous type new { ... }.

You'll need to do something along the lines of

var routeValues = new RouteValueDictionary();

routeValues.Add("filePath", filePath);

for (int i = 0; i < searchTerms.Count(); i++)
{
    var key = String.Format("searchTerms[{0}]", i);
    routeValues.Add(key, searchTerms[i]);
}

// ...

.DataBinding(dataBinding => dataBinding.Ajax()
    .Select("MyGridAction", "MyController", routeValues)) 
// don't have a compiler with me so this may be the wrong overload

// ...

This means that each individual item has its own key so the model binder can play nicely with it.

For more information, read this blog post by Scott Hanselman.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top