0

On my home (index) page I have two partials, one renders a search form and the other results from the search:

<div class="row-fluid well">
    <div class="span6">
        @Html.Partial("~/Views/Search/_BasicPropertySearchPartial.cshtml")
    </div>
    <div class="span6" id="basic-property-search-results">
        @Html.Partial("~/Views/Search/_BasicPropertySearchResultsPartial.cshtml")
    </div>
</div>

In my SearchController a GET action returns the search form:

[HttpGet]
public ActionResult BasicPropertySearch()
{
    return PartialView("_BasicPropertySearchPartial");
}

And a POST action gets user input from the form and returns results based on a query:

[HttpPost]
public ActionResult BasicPropertySearch(BasicPropertySearchViewModel viewModel)
{
    var predicate = PredicateBuilder.True<ResidentialProperty>();
    if (ModelState.IsValid)
    {
        using(var db = new LetLordContext())
        {
            predicate = predicate.And(x => x.HasBackGarden);
            //...
            var results = db.ResidentialProperty.AsExpandable().Where(predicate).ToList();

            GenericSearchResultsViewModel<ResidentialProperty> gsvm = 
                    new GenericSearchResultsViewModel<ResidentialProperty> { SearchResults = results };

            return PartialView("_BasicPropertySearchResultsPartial", gsvm);
        }            
    }
    ModelState.AddModelError("", "Something went wrong...");
    return View("_BasicPropertySearchPartial");
}

I've created a generic view model because search results may be lists of different types:

public class GenericSearchResultsViewModel<T>
{
    public List<T> SearchResults { get; set; }

    public GenericSearchResultsViewModel()
    {
        this.SearchResults = new List<T>();
    }
}

The POST action returns the following view:

@model LetLord.ViewModels.GenericSearchResultsViewModel<LetLord.Models.ResidentialProperty>

@if (Model.SearchResults == null) // NullReferenceException here!
{
    <p>No results in list...</p>
}
else
{
    foreach (var result in Model.SearchResults)
    {
    <div>
        @result.Address.Line1
    </div>
    }
}

I've put breakpoints on the GET and POST actions and the exception is being thrown before either or hit.

Is this problem being caused because index.cshtml is being rendered before it has a chance to do the GET/POST in the SearchController?

If so, does this mean it's a routing problem?

Finally, I thought newing SearchResults in the constructor would overcome NullReferenceExceptions?

Feedback appreciated.

8
  • It seems that the whole Model is null. If the ModelState.IsValid property returns false in your postback action, you are returning a view without a model. Might that be the problem? Commented Apr 3, 2013 at 10:42
  • As per my question, I've a breakpoint on both actions and neither are being hit so I don't think it's that. Maybe I need to check in Index.cshtml is the list null before rendering the search results...? Commented Apr 3, 2013 at 10:46
  • If you are getting a NullReferenceException at the statement Model.SearchResults, the Model must be null. If you can confirm that in the debugger, you should set breakpoints on every return statement (return View(...)) to get a clue which one forces the view to render. Your Index view is returned anywhere else, not in one of the actions you posted above. What's the name of the partial view causing the exception? Is it rendered through your Html.Partial calls? They lack a model, too. Commented Apr 3, 2013 at 10:51
  • Okay you've got me thinking. Index action is in the HomeController, and it isn't returning anything, just return View() (which contains the first code segmant from the question). The partial that's causing the exception is BasicPropertySearchResultsPartial. So do you think Index is rendering that partial before it gets a chance to call the actions from the SearchController? Commented Apr 3, 2013 at 11:04
  • The child actions are not called at all through your Index action. For using child actions (which then can return a partial view) you need to use Html.Action not Html.Partial. Commented Apr 3, 2013 at 11:12

1 Answer 1

1

It seems that the whole Model is null. You need to either supply a partial view model to the Html.Partial calls or use Html.Action to call the two controller (child) actions with the action and controller names.

See the MSDN for details.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.