Alexander Combe
Alexander Combe

Reputation: 61

When I render a partial view my Model is Null

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;
    }
}

Upvotes: 4

Views: 2566

Answers (2)

ADyson
ADyson

Reputation: 61839

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.

Upvotes: 0

Emre Kabaoglu
Emre Kabaoglu

Reputation: 13146

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.

Upvotes: 4

Related Questions