0

I have two model in a Asp.net core project: Person and Address:

class Person
{
    public int Id {get;set;}
    public string Name {get;set;}
    public int? HomeAddressId {get;set;}
    public Address HomeAddress {get;set;}   
}

class Address
{
    public int Id {get;set;}
    public string CityName {get;set;}
    ...
}

In the person create view I need to include the fields for address attribute using a partial view for that.

How to include this partial (or write this partial) in a way that the names of elements match the correct attributes from person model?

Ex.:

<input name="HomeAddress.CityName" />

Remembering that this view should be used in another models other than person.

Beetlejuice
  • 4,292
  • 10
  • 58
  • 84
  • I have not dug into this but you could potentially build a custion DisplayName Attribute and utilize it. https://msdn.microsoft.com/en-us/library/system.componentmodel.displaynameattribute(v=vs.110).aspx – John Hartsock Mar 24 '16 at 17:48
  • In your address view, you could do the following: @Html.TextBox("HomeAddress.CityName",Model.CityName) and you could call it from within your Person view like this: @Html.Partial("_Address",Model.HomeAddress). I'm curious as to your overall goal. With what I've described you will be limited to every address being a home address. – Papa Burgundy Mar 24 '16 at 18:37
  • @PapaBurgundy, in fact, the models has only one address attribute (HomeAddress is just an example). – Beetlejuice Mar 24 '16 at 18:50
  • You do not what to use a partial (you could but then you need to pass the `HtmlFieldPrefix` as per [this answer](http://stackoverflow.com/questions/29808573/getting-the-values-from-a-nested-complex-object-that-is-passed-to-a-partial-view/29809907#29809907)). –  Mar 24 '16 at 20:35
  • The correct approach is to use an `EditorTemplate`. Rename your partial to `/Views/Shared/EditorTemplates/Address.cshtml` and in the view use `@Html.EdiitorFor(m => m.HomeAddress)` - the correct prefixes will be added by the `EditorFor()` method. –  Mar 24 '16 at 20:36

2 Answers2

0

@Beetlejuice There is probably a better more clever way but this might help you for now? You'd want to tinker with that and get it bound to a model (so you can use razor and validation and such). Maybe ViewBag could work in combination with a Model to set the name attribute. Either way this general flow can accomplish it.

Calling View :

@{ Html.RenderAction("Partial", "Home", new { id = "HomeAddress" }); }

Controller :

Public ActionResult Partial(string id)
  {
        return PartialView((object)id);
  }

Partial.cshtml

@model string

@{
   string Id = Model + ".Id ";
   string name = Model + ".CityName";
}

<input type="text" name="@Id" />
<input type="text" name="@name" />
Mike Wallace
  • 543
  • 4
  • 15
  • Hum.. I got the point. Looks promising. I will try something similar to this, but passing the Address model to the partial view, instead a string. – Beetlejuice Mar 24 '16 at 18:27
  • Yeah that's a really crude example. That flow along with what you already know should be enough to tailor something that works well. – Mike Wallace Mar 24 '16 at 18:28
0

You can create an extension method to generate a partial view which allows you to pass a model prefix, like in this post: ASP.MVC 3 Razor Add Model Prefix in the Html.PartialView extension

public static void RenderPartialWithPrefix(this HtmlHelper helper, string partialViewName, object model, string prefix)
{
    helper.RenderPartial(partialViewName,
                         model,
                         new ViewDataDictionary { 
                            TemplateInfo = new System.Web.Mvc.TemplateInfo { 
                                HtmlFieldPrefix = prefix 
                            } 
                        });
}

And then call it from your main view like this:

@Html.RenderPartialWithPrefix("MyPartialViewName", Model.HomeAddress, "HomeAddress");
Community
  • 1
  • 1
thiag0
  • 2,199
  • 5
  • 31
  • 51