HiveBrain v1.2.0
Get Started
← Back to all entries
patterncsharpMinor

Controller for searching with certain parameters

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
searchingwithcontrollerforcertainparameters

Problem

In the index view a user can search with any combination of one to all of the following parameters: firstname, lastname or ssn. The found search results are displayed in the search results view. In my HomeOfficeController I have written the code like this, but most of the code is repeating.

Can someone suggest a neater way of writing this code?

```
[HttpPost]
public ActionResult Index(HomeOfficeViewModel viewModel)
{
TempData["FirstName"] = viewModel.FirstName;
TempData["LastName"] = viewModel.LastName;
TempData["SSN"] = viewModel.FullSsn;
return RedirectToAction("SearchResults", "HomeOffice");
}

public ActionResult SearchResults(HomeOfficeViewModel viewModel, UserSessionContext sessionContext)
{
TempData.Keep();
if (TempData["FirstName"] != null)
{ viewModel.FirstName = TempData["FirstName"].ToString(); }
if (TempData["LastName"] != null)
{ viewModel.LastName = TempData["LastName"].ToString(); }
if (TempData["SSN"] != null)
{ viewModel.FullSsn = TempData["SSN"].ToString(); }

if (viewModel.FirstName != null && viewModel.LastName == null && viewModel.FullSsn == null)
{
var ph = _policyHolderRepository.Where(x => x.FirstName == viewModel.FirstName).ToList();
if (ph.Count != 0)
{
var searchresults = from p in ph
select new SearchResultsViewModel
{
FullSsn = p.Ssn,
FullName = p.FirstName + " " + p.LastName,
UserId = p.UserId,
AccountVerified = p.AccountVerified
};
ViewData["FirstName"] = ">> is '" + viewModel.FirstName + "'";

Solution

You could look at putting the core of the logic into a service layer. This will help keep the controller skinny as well as help with writting unit tests as well. I wrote this in notepad so it's not tested but gives an idea of what I mean.

This could be done even more by things such as providing a way to expose properties for the displaymessage rather than having it hard coded to '>>' etc This would give more power to the view to determine how to render the message.

public ActionResult Index(HomeOfficeViewModel viewModel)
{

    HomeOfficeQueryService service = new HomeOfficeQueryService();
    List searchResults = new List();

    try
    {
        if(!ModelState.IsValid())
        {
            throw new NoResultsException(""); 
        }

        var critera = service.GetCriteria(viewModel);
        searchResults = service.GetQuery(criteria).ToList();            
    }
    catch(NoResultsException ex)
    {
        if(ex.GetMessage().Length() > 0)
            ModelState.AddModelError("Error", ex.GetMessage());         
    }
    finally
    {
        return View("SearchResults", new SearchResultsViewModel()
            {
                PolicyOwnerFirstName = sessionContext.LoggedInUserFullName,
                LastLoggedOnDate = sessionContext.LoggedInUserLastLoggedOnDate, 
                SearchResults = searchResults
            });     
    }
}
class HomeOfficeQueryCriteria 
{
    public Predicate Criteria { get; set; }
    public string EmptySearchMessage { get; set; }
    public string DisplayMessage { get; set; }
}

class HomeOfficeQueryService()
{
    private Repository _policyHolderRepository;

    public HomeOfficeQueryService(Repository policyHolderRepository)
    {
        _policyHolderRepository = policyHolderRepository;
    }

    public HomeOfficeQueryCriteria GetCriteria(HomeOfficeViewModel viewModel)
    {
        if(!string.isNullOrWhiteSpace(viewModel.FirstName) && string.isNullOrWhiteSpace(viewModel.LastName) && string.isNullOrWhiteSpace(viewModel.FullSsn))
        {
            return new HomeOfficeQueryCriteria()
            {
                Criteria = (x) => x.FirstName == viewModel.FirstName,
                EmptySearchMessage = "First Name searched does not exist in our records".
                DisplayMessage = ">> is '" + viewModel.FirstName + "'";
            };
        }
        else if (viewModel.FirstName == null && viewModel.LastName != null && viewModel.FullSsn == null)
        {
            // fill out more criteria here
        }
        else if (viewModel.FirstName != null && viewModel.LastName != null && viewModel.FullSsn == null)
        {
            // fill out more criteria here
        }
        else if (viewModel.FirstName != null && viewModel.LastName != null && viewModel.FullSsn != null)
        {
            // fill out more criteria here
        }
        else
        {
            // Any more conditions here
        }

    }

    public IQueryable GetQuery(HomeOfficeQueryCriteria arg) where T : HomeOfficeViewModel
    {
        var items = _policyHolderRepository.Where(x => arg.Criteria);

        if(items.Any()
        {
            var query = var searchresults = from p in ph
                        select new SearchResultsViewModel
                                   {
                                       FullSsn = p.Ssn,
                                       FullName = p.FirstName + " " + p.LastName,
                                       UserId = p.UserId,
                                       AccountVerified = p.AccountVerified
                                   };

            return query;
        }
        else
        {
            throw NoResultsException(arg.EmptySearchMessage);
        }
    }
}

Code Snippets

public ActionResult Index(HomeOfficeViewModel viewModel)
{

    HomeOfficeQueryService service = new HomeOfficeQueryService();
    List<HomeOfficeViewModel> searchResults = new List<HomeOfficeViewModel>();

    try
    {
        if(!ModelState.IsValid())
        {
            throw new NoResultsException(""); 
        }

        var critera = service.GetCriteria(viewModel);
        searchResults = service.GetQuery(criteria).ToList();            
    }
    catch(NoResultsException ex)
    {
        if(ex.GetMessage().Length() > 0)
            ModelState.AddModelError("Error", ex.GetMessage());         
    }
    finally
    {
        return View("SearchResults", new SearchResultsViewModel()
            {
                PolicyOwnerFirstName = sessionContext.LoggedInUserFullName,
                LastLoggedOnDate = sessionContext.LoggedInUserLastLoggedOnDate, 
                SearchResults = searchResults
            });     
    }
}
class HomeOfficeQueryCriteria 
{
    public Predicate<HomeOfficeViewModel> Criteria { get; set; }
    public string EmptySearchMessage { get; set; }
    public string DisplayMessage { get; set; }
}

class HomeOfficeQueryService()
{
    private Repository<T> _policyHolderRepository;

    public HomeOfficeQueryService(Repository<T> policyHolderRepository)
    {
        _policyHolderRepository = policyHolderRepository;
    }

    public HomeOfficeQueryCriteria GetCriteria(HomeOfficeViewModel viewModel)
    {
        if(!string.isNullOrWhiteSpace(viewModel.FirstName) && string.isNullOrWhiteSpace(viewModel.LastName) && string.isNullOrWhiteSpace(viewModel.FullSsn))
        {
            return new HomeOfficeQueryCriteria()
            {
                Criteria = (x) => x.FirstName == viewModel.FirstName,
                EmptySearchMessage = "First Name searched does not exist in our records".
                DisplayMessage = "<<< First Name >>> is '" + viewModel.FirstName + "'";
            };
        }
        else if (viewModel.FirstName == null && viewModel.LastName != null && viewModel.FullSsn == null)
        {
            // fill out more criteria here
        }
        else if (viewModel.FirstName != null && viewModel.LastName != null && viewModel.FullSsn == null)
        {
            // fill out more criteria here
        }
        else if (viewModel.FirstName != null && viewModel.LastName != null && viewModel.FullSsn != null)
        {
            // fill out more criteria here
        }
        else
        {
            // Any more conditions here
        }

    }

    public IQueryable<SearchResultsViewModel> GetQuery(HomeOfficeQueryCriteria arg) where T : HomeOfficeViewModel
    {
        var items = _policyHolderRepository.Where(x => arg.Criteria);

        if(items.Any()
        {
            var query = var searchresults = from p in ph
                        select new SearchResultsViewModel
                                   {
                                       FullSsn = p.Ssn,
                        

Context

StackExchange Code Review Q#3899, answer score: 2

Revisions (0)

No revisions yet.