Umut Esen Umut Esen - 11 days ago 5
C# Question

MVC empty query string paramater strange behaviour

I'm trying to implement search by passing the keyword to controller action as a parameter as shown below:

public ActionResult Index(string query)
{
var contacts = _unitOfWork.Contacts.GetContacts(_user.Id, query);
var viewModel = contacts.Select(Mapper.Map<Contact, ContactViewModel>);
return View("Index", viewModel);
}


GetContacts
function in the repository looks like the following:

public IEnumerable<Contact> GetContacts(int userId, string query = null)
{
var list = _context.Contacts
.Where(c => c.UserId == userId)
.OrderBy(c => c.FirstName)
.AsQueryable();

if (query != null)
list = list.Where(c => c.FirstName.ToLower().Contains(query.ToLower())
|| c.LastName.ToLower().Contains(query.ToLower()));

return list.ToList();
}


When I navigate to
http://localhost:50139/contacts/index?query=
, I get an empty list. Having stepped through the code it is apparent that the
query
parameter is converted to an empty string value.
To ensure the search works, I have the following tests and all of them pass:

GetContacts_SearchByFirstName_ShouldReturnFilteredList
GetContacts_SearchByLastName_ShouldReturnFilteredList
GetContacts_SearchWithCapitalLetters_ShouldReturnFilteredList
GetContacts_SearchWithNullQuery_ShouldReturnAllContacts


In particular, the following test runs the function with empty string, which also passes successfully.

[TestMethod]
public void GetContacts_SearchWithEmptyString_ShouldReturnAllContacts()
{
var contactList = new List<Contact>()
{
// Construct new contact with first and last name and associated user id.
new Contact("e", "b",_userId ),
new Contact("c", "b",_userId ),
new Contact("a", "b",_userId ),
new Contact("d", "b",_userId )
};

_mockContacts.SetSource(contactList);

var result = _repository.GetContacts(_userId, "");

result.Count().Should().Be(4);
}


I have 3 contacts in the database and I can see all of them when I don't pass the query parameter. I would appreciate if you could point out why the controller action returns an empty list.

Answer

When you pass an empty string to the query parameter, the condition if(query!=null) fails and the line below that

list = list.Where(c => c.FirstName.ToLower().Contains(query.ToLower())
            || c.LastName.ToLower().Contains(query.ToLower()));

gets executed, which checks the database for an entry with empty string in the LastName. This condition never gets satisfied and hence your list gets overridden with an empty list.