Bitz
Bitz

Reputation: 1148

Best way to handle returning no results when trying to find a model?

I am trying to teach myself MVC 6 using online sources, but they do not always cover exactly what I am trying to learn. Apologies if I seem ignorant to something that should be fairly obvious.

In this case, I am passing data to the view using:

   public ActionResult Index(int? id)
    {
        foreach (Customer c in _cList)
        {
            if (c.Id == id)
            {
                return View(c);
            }
        }
        return View(new Customer());
    }

Is returning the view with an empty model the best way of dealing with a "no matching id" result of a foreach search?

The view then calls the model as such:

@if (Model.Id != 0)
{
    <P> @Model.Name </P>
    <P> @Model.Email </P>
}
else
{
    <P> Nothing found!</P>
}

While it does infact work, I would like to know if this is the right way to handle this. It just feels a bit... hacky. Creating an empty model just to return with an object that won't cause a null pointer exception?

While it shouldn't be necessary information- the _cList is declared as private readonly List<Customer> _cList = new List<Customer>() as an inline pseudo database - For those of who who are finding this via google and are curious. It makes foreach work and therefore simplifies the searching. Not idealistic in an actual SQL Query search. A scalar function might be what you will have to use.

Upvotes: 2

Views: 1779

Answers (1)

Orel Eraki
Orel Eraki

Reputation: 12196

There is a bigger problem that you missed. MVC is Model, View(ViewModel) and Controller.

Controller in MVC should return a ViewModel describing the Model and not the model it self.

A more proper implementation will be creating a ViewModel which will reflect the model for the view.

ViewModel

public class SomeViewModel
{
    public Customer Customer { get; set; }
    public string Error { get; set; } // Or a boolean HasErrors property.
}

Controller

public ActionResult Index(int? id)
{
    var foundController = _cList.FirstOrDefault(c => c.Id == id);
    var viewModel = new SomeViewModel
    {
        Customer = foundController
    };
    if (foundController == null)
    {
        viewModel.Error = "No matches found!"
    }
    return View(viewModel);
}

View

@model SomeViewModel

@if (Model.Error == null)
{
    <P> @Model.Error</P>
}
else
{
    <P> @Model.Name </P>
    <P> @Model.Email </P>
}

At your page there is no big change and you can validate if there is an error. Of course in this scenario you should leave Customer as null.

This solution will give you more flexibility and you can add as many properties as you need for describing the page needs.

Note: Code has not been tested.

Upvotes: 1

Related Questions