0

I have an autocompleter as a partial view which I would like to use twice in the same page. There are three models involved

public partial class CustomParent
{

    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Int64 CustomParentId { get; set; }

    public Geoname ParentGeoname { get; set; }
    public Geoname ChildGeoname { get; set; }

    public CustomParent()
    {
        ParentGeoname = new Geoname();
        ChildGeoname = new Geoname();
    }
}
public partial class Geoname
{
    [Required]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Int64 GeonameId { get; set; }
    public string Name { get; set; }
}
public partial class GeonameWithFilter
{
    public GeonameWithFilter()
    {
        FilterString = "";
    }
    public Geoname Geoname { get; set; }
    public String FilterString { get; set; }
}

I have a controller set up

    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Create([Bind(Include = "CustomParentId,ParentGeoname,ChildGeoname")] CustomParent customParent)
    {...}

I set up the two Html partials on my create view initially only using the customparent and geoname models and it worked fine setting the values in of the parent and child geonames as expected. I now require additional parameters to be passed to the partial view so I created an encapsulating class (GeonameWithFilter). I made changes to my partial view and to my two html.partials on the view page which now look like this :

            @Html.Partial("_GeonameAutocomplete",new GeonameWithFilter(){Geoname = Model.ParentGeoname,FilterString="'featurecodes':'CUPA'"},
                new ViewDataDictionary()
                {
                    TemplateInfo = new TemplateInfo() { HtmlFieldPrefix = "ParentGeoname" }
                })
            @Html.Partial("_GeonameAutocomplete", new GeonameWithFilter() { Geoname = Model.ChildGeoname, FilterString = "'featurecodes':'ADM1,ADM2,ADM3,ADM4'" },
                new ViewDataDictionary()
                {
                    TemplateInfo = new TemplateInfo() { HtmlFieldPrefix = "ChildGeoname" }
                })

The problem is that the customparent.parentGeoname and customparent.childGeoname are not now getting returned to my controller. I'm guessing this is because the partial view's model is not the same class as my page models parentGeoname and childGeoname but cannot work out or find any examples of how to handle such a circumstance if indeed it is possible.

1 Answers1

0

Well - it took me most of a day, but I now have what I required.

I gave up on the encapsulation and instead added my basic geoname model to the new ViewDataDictionary and nullified the default model for the Html.Partial.

I then added the filterstring parameter as a key in a new ViewDataDictionary which I used as the argument for the one with the model and TemplateInfo.

Many thanks to https://stackoverflow.com/users/7714/craig-stuntz for his answer to a different question Shorthand for creating a ViewDataDictionary with both a model and ViewData items? that pointed me in the direction I have gone.

My autocompleter now just use @ViewData["FilterString"] to access the filter parameters. The GeonameWithFilter encapsulation is no longer needed. My two Html.Partials on my view page now look like this:

            @Html.Partial("_GeonameAutocomplete", null,
                new ViewDataDictionary(new ViewDataDictionary() { {"FilterString",  "featurecodes:'CUPA'"  }})
                {
                    Model = Model.ParentGeoname,
                    TemplateInfo = new TemplateInfo { HtmlFieldPrefix = "ParentGeoname" }
                })
            @Html.Partial("_GeonameAutocomplete", null,
                new ViewDataDictionary(new ViewDataDictionary() { { "FilterString", "featurecodes:'ADM1,ADM2,ADM3,ADM4'" } })
                {
                    Model = Model.ChildGeoname,
                    TemplateInfo = new TemplateInfo { HtmlFieldPrefix = "ChildGeoname" }
                })

If anyone knows a better way to achieve the end result I would still like to hear it.

Community
  • 1
  • 1