开发者

ASP.NET MVC Search

Hi I'm building a very simple search sys开发者_开发知识库tem using ASP.NET MVC. I had it originally work by doing all the logic inside the controller but I am now moving the code piece by piece into a repository. Can anyone help me do this. Thanks.

Here is the original Action Result that was in the controller.

public ActionResult Index(String query)
        {
            var ArticleQuery = from m in _db.ArticleSet
                               select m;

            if (!string.IsNullOrEmpty(query))
            {
                ArticleQuery = ArticleQuery.Where(m => m.headline.Contains(query) orderby m.posted descending);
            }

            return View(ArticleQuery.ToList());
        }

As you can see, the Index method is used for both the initial list of articles and also for the search results (they use the same view).

In the new system the code in the controller is as follows:

public ActionResult Index()
    {
        return View(_repository.ListAll());
    }

The Repository has the following code:

public IList<Article> ListAll()
{
    var ArticleQuery = (from m in _db.ArticleSet

                        orderby m.posted descending select m);

    return ArticleQuery.ToList();
}

and the Interface has the following code:

public interface INewsRepository
{
    IList<Article> ListAll();
}

So what I need to do is now add in the search query stuff into the repository/controller methods using this new way. Can anyone help? Thanks.

EDIT: The INewsRespository file as it looks now:

namespace MySuperAwesomeApp.Models
{
    public interface INewsRepository
    {
        IList<Article> ListAll();

        //Article Details(int id);

        //Article Create([Bind(Exclude = "Id")]Article articleToCreate);
    }
}


Your interface INewsRepository needs to have the following added:

IList<Article> Search(string query);

Repository

Then in the NewsRepository that implements INewsRepository:

public IList<Article> INewsRespository.Search(string query)
{
    var articleQuery = (from m in _db.ArticleSet
                        where m.headline.Contains(query)
                        orderby m.posted descending select m).ToList();
}

In the controller, you handle the case where the query doesn't contain information:

Controller

//just for this example. You should look at DI/IoC for Real World Usage.
INewsRepository repository; 
public ActionResult ListArticles(string query)
{
    repository = new NewsRepository();
    List<Article> articles = new List<Article>();
    if (string.IsNullOrEmpty(query))
    {
        articles = repository.ListAll();
    }
    else 
    { 
        articles = repository.Search(query);
    }
    return View(articles);
}


Look at my code samples in the answer to this question - hope they will help you...


George was close, but his code won't compile (articleQuery is out of scope at the return)

// public IList<Article> IRespository.Search(string query)
public IList<Article> Search(string query)
{
    var articleQuery = (from m in _db.ArticleSet orderby m.posted descending select m);
    return (string.IsNullOrEmpty(query))
        ? articleQuery.ToList()  // I'm not 100% sure if ToList is required
        : articleQuery.Where(m => m.headline.Contains(query)).ToList();
}

UPDATE: Ok, your code should ultimately look like this:

public interface INewsRepository
{
    IList<Article> Search(string query);
    IList<Article> ListAll();  // You need this too, right?
}

public class NewsRepository : INewsRepository
{
    public IList<Article> Search(string query)
    {
        // Code as above.
    }

    public IList<Article> ListAll()
    {
        // Code as in your question.
    }
}

Update 2 (@Cameron url question)

Throw the following code into your controller for a moment and see what result you get:

public ActionResult Index(string query)
{
    Response.Write("The Query string was :" + query);
    return new EmptyResult();
}

And see what you get. If you don't see some message, then you must be routing to another controller/action. If you get nothing, try http://localhost:8888/home/index?query=henry


This should do the trick:

public IList<Article> SearchByTitle(string query){
    var q=_db.ArticleSet;
    if (!string.IsNullOrEmpty(query))    
        q=q.Where(a=>a.Title.Contains(query));
    return q.OrderBy(x=>x.Title).ToList();
}

And You might benefit from investigating my current search implementation. There is no paging though and it's more like filtering instead of searching. It uses Linq to NHibernate underneath.

Html:

@model SearchCriteria
@using (Html.BeginForm("Search","Applications",FormMethod.Post)){
<span>@Html.ShowLink("Search applications...","searchbox")</span>
<fieldset class="searchapplications">
 <legend>@Html.HideLink("Search applications:","searchbox",container:"fieldset")</legend>
 <table class="alignright" style="width:100%;">
  <tr>
   @Html.TDInputFor(x=>x.ProjectIndex)
   @Html.TDInputFor(x=>x.OpeningStatus)
   <td>
   Duration from @Html.EditorFor(x=>x.DurationFrom)
   to @Html.EditorFor(x=>x.DurationTo)
   </td>
  </tr>
  <tr>
   @Html.TDInputFor(x=>x.Acronym)
   @Html.TDInputFor(x=>x.AdmStatus)
   <td>
   Requested grant from @Html.EditorFor(x=>x.RequestedGrantFrom)
   to @Html.EditorFor(x=>x.RequestedGrantTo)
   </td>
  </tr>
  <tr>
   @Html.TDInputFor(x=>x.Priority)
   @Html.TDInputFor(x=>x.EligStatus)
   <td>
   Score from @Html.EditorFor(x=>x.QualScoreFrom)
   to @Html.EditorFor(x=>x.QualScoreTo)
   </td>
  </tr>
  <tr>
   @Html.TDInputFor(x=>x.Applicant)
   @Html.TDInputFor(x=>x.QualStatus)
 </tr>
 <tr>
   <td colspan="2"></td>
   @Html.TDInputFor(x=>x.JMCDecision)
   <td colspan="2"></td>
 </tr>
 </table>
 @Html.HiddenFor(x=>x.SortBy)
 @Html.HiddenFor(x=>x.SortAsc)
 <br />
 <br />
 <input type="submit" value="Search" />
</fieldset>
}

Controller:

public class ApplicationsController{
 [HttpPost]
 public ActionResult Search(SearchCriteria input){
   if(input==null) input=Session[Critkey] as SearchCriteria??new SearchCriteria();
   Session[Critkey]=input;
   var applications=_applications.Search(input);
   var mapped=this.MapList<Application,ApplicationModel>(applications);
   return View(new SearchModel {Applications=mapped,SearchCriteria=input});
 }
}

And repository + SearchCriteria class:

  public class AllApplications:IAllApplications{    
    public IEnumerable<Application> Search(SearchCriteria inp){
      var c=_session.Query<Application>();
      c=ApplicationSearchEagerLoading.Attach(c);
      var q=c.AsQueryable();
      q=AddSearchFilters(inp,q);
      if(!string.IsNullOrEmpty(inp.SortBy)){
        var s=SearchCriteria.SortByTranslations[inp.SortBy];
        q=(inp.SortAsc?q.OrderBy(s):q.OrderByDescending(s)).AsQueryable();
      }
      return q.AsEnumerable();
    }      
    private static IQueryable<Application> AddSearchFilters
       (SearchCriteria inp,IQueryable<Application> q){
      if(!string.IsNullOrEmpty(inp.Acronym))
        q=q.Where(a=>a.Project.Acronym.Contains(inp.Acronym));
      if(!string.IsNullOrEmpty(inp.Applicant))
        q=q.Where(a=>a.Project.Applicant.Name.Contains(inp.Applicant));
      if(!string.IsNullOrEmpty(inp.Priority))
        q=q.Where(a=>a.Project.Priority.Name.Contains(inp.Priority));
      if(!string.IsNullOrEmpty(inp.ProjectIndex))
        q=q.Where(a=>a.Project.ProjectIndex.Contains(inp.ProjectIndex));
      if(inp.OpeningStatus!=null)
        q=q.Where(a=>a.OpeningStatus==inp.OpeningStatus);
      if(inp.AdmStatus!=null)
        q=q.Where(a=>a.AdmCheck.Status==inp.AdmStatus);
      if(inp.EligStatus!=null)
        q=q.Where(a=>a.EligCheck.Status==inp.EligStatus);
      if(inp.QualStatus!=null)
        q=q.Where(a=>a.QualAssessmentStatus==inp.QualStatus);
      if(inp.JMCDecision!=null)
        q=q.Where(a=>a.JMCDecision==inp.JMCDecision);
      if(!string.IsNullOrEmpty(inp.DurationFrom)
         &&!string.IsNullOrEmpty(inp.DurationTo))                   
      q=q.Where(a=>a.Project.Description
                .DurationInMonths>=inp.DurationFrom.ExtractNumber()
             &&a.Project.Description
                .DurationInMonths<=inp.DurationTo.ExtractNumber());
      else{
        if(!string.IsNullOrEmpty(inp.DurationFrom))
          q=q.Where(a=>a.Project.Description
             .DurationInMonths>=inp.DurationFrom.ExtractNumber());
        if(!string.IsNullOrEmpty(inp.DurationTo))               
          q=q.Where(a=>a.Project.Description
            .DurationInMonths<=inp.DurationTo.ExtractNumber());
      }              
      //...
      return q;
    }
  }

  public class SearchCriteria{
    internal static Dictionary<string,Func<Application,object>>
    SortByTranslations=new Dictionary<string,Func<Application,object>>
                         {
                           {"ProjectIndex",x=>x.Project.IndexNr},
                           {"Acronym",x=>x.Project.Acronym},
                           {"Applicant",x=>x.Project.Applicant.Name},
                           {"Priority",x=>x.Project.Priority.Name},
                           {"OpeningStatus",x=>x.OpeningStatus},
                           {"AdmStatus",x=>x.AdmCheck.Status},
                           {"EligStatus",x=>x.EligCheck.Status},
                           {"QualStatus",x=>x.QualAssessmentStatus},
                           {"JMCDecision",x=>x.JMCDecision},
                         };
    public string RequestedGrantTo{get;set;}
    public string RequestedGrantFrom{get;set;}
    public string DurationFrom{get;set;}
    public string DurationTo{get;set;}
    public string QualScoreFrom{get;set;}
    public string QualScoreTo{get;set;}
    public QualAssessmentStatus QualStatus{get;set;}
    public EligCheckStatus EligStatus{get;set;}
    public AdmCheckStatus AdmStatus{get;set;}
    public OpeningStatus OpeningStatus{get;set;}
    public JMCDecision JMCDecision{get;set;}
    public string Applicant{get;set;}
    public string Priority{get;set;}
    public string Acronym{get;set;}
    public string ProjectIndex{get;set;}
    public string SortBy{get;set;}
    public bool SortAsc{get;set;}
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜