4

I am trying to Render a view which consists of just a DropDownList inside another View in ASP.NET MVC but for some reason the Model is Null. I think it's because I am only calling the view and the Controller isn't being called at all. Where am I going wrong? maybe my phone approach is incorrect.

Dropbox View

@model MyWatch.Models.Countries
@{ 
    ViewBag.Title = "CountrySearch";
    Layout = null;
    if (Model != null)
    {
        Html.DropDownListFor(m => m.countries, new SelectList(Model.countries.Select(s => new SelectListItem { Text = s.name, Value = s.code })));
    }
    else
    {
        Html.DropDownListFor(m => m.countries, new SelectList(new List<String>()));
    }
}

Main View

<div class="form-group">
    @Html.LabelFor(m => m.Country, new { @class = "col-md-2 control-label" })
    <div class="col-md-10">
        @{Html.RenderPartial("Search/CountrySearch");}
    </div>
</div>

Controller

    public ActionResult CountrySearch()
    {
        try
        {
            using (StreamReader streamReader = new StreamReader("C:\\Users\\Alex Combe\\Documents\\Visual Studio 2015\\Projects\\MyWatch\\MyWatch\\App_Data\\CountryList.json"))
            {
                string json = streamReader.ReadToEnd();
                Countries countries = new Countries();
                countries.countries = JsonConvert.DeserializeObject<IList<Country>>(json);
                return View(countries);
            }
        }
        catch (FileNotFoundException e)
        {
            Console.WriteLine(e.StackTrace);
            return View(new Countries());
        }
    }
}

Model

namespace MyWatch.Models
{
    public class Country
    {
        public string name { get; set; }
        public string code { get; set; }
        public SelectList selectList { get; set; }
    }

    public class Countries
    {
        public IList<Country> countries;
    }
}
halfer
  • 19,824
  • 17
  • 99
  • 186
  • 1
    because you're not passing your model to the partial view, e.g. `Html.RenderPartial("Search/CountrySearch", Model);` – derloopkat Jan 10 '18 at 11:39
  • 2
    Possible duplicate of [MVC 4 - how do I pass model data to a partial view?](https://stackoverflow.com/questions/15148103/mvc-4-how-do-i-pass-model-data-to-a-partial-view) – derloopkat Jan 10 '18 at 11:40
  • 1
    Instead of RenderPartial, use the Action() method. RenderPartial won't pass though the controller, it goes straight to the view. – Zorkind Jan 10 '18 at 11:44

2 Answers2

4

You are trying to render a view directly, you should call controller action first. Use Html.RenderAction instead;

<div class="col-md-10">
    @{Html.RenderAction("CountrySearch","Search");}
</div>

And return PartialView instead of View;

return PartialView(countries);

Also, DropDownListFor first parameter should be selected item.

Html.DropDownListFor(m => m.SelectedItem, new SelectList(Model.countries.Select(s => new SelectListItem { Text = s.name, Value = s.code })));

And change your model too;

public class Countries
{
    public string SelectedItem { get; set; }
    public IList<Country> countries;
}

And be sure about that CountryList.json has valid data for your model.

lucky
  • 12,734
  • 4
  • 24
  • 46
  • Hey, thank you very much to both of you for your feedback. I've made the changes you have suggested but now I'm getting the following InnerException when I try to render the Register Page: `InnerException {"The controller for path '/Account/Register' was not found or does not implement IController."} System.Exception {System.Web.HttpException}` – Alexander Combe Jan 12 '18 at 10:10
  • @AlexanderCombe that error appears to be unrelated to the code here, you should make a separate question about it, with relevant code. – ADyson Jan 12 '18 at 10:28
  • As @ADyson described, it is unrelevant with this question. – lucky Jan 12 '18 at 10:31
0

The @Html.Partial and @Html.RenderPartial methods are not meant to call the Controller’s Action method, instead these methods will directly populate the Partial View's markup from the given model and render it. If no model is passed, then it will just render the view markup as if the model was empty.

If you want to use RenderPartial, you need to pass it a model object directly in the method, as the second parameter - see the documentation at https://msdn.microsoft.com/en-us/library/system.web.mvc.html.renderpartialextensions.renderpartial(v=vs.118).aspx#M:System.Web.Mvc.Html.RenderPartialExtensions.RenderPartial%28System.Web.Mvc.HtmlHelper,System.String,System.Object%29

e.g. @Html.RenderPartial("Search/CountrySearch", yourModelObject)

If you want to do it via your controller action, you have to call @Html.RenderAction("CountrySearch", "Search") instead, and have the CountrySearch method end with return PartialView instead of return View.

ADyson
  • 57,178
  • 14
  • 51
  • 63