0

I have a complex type License as a view model.

public class License
{
    public string Name { get; set; }

    //  Other Properties

    public List<Function> Functions { get; set; }
}

public class Function
{
    public string Name { get; set; }

    //  Other Properties

    public List<Unit> Units { get; set; }
}

public class Unit
{
    public string Name { get; set; }

    //  Other Properties
}

Both the Function's view template and Unit's view template are dynamiclly rendered. So the html looks like this:

<!-- LicenseView -->
@model License

@Html.TextBoxFor(m => m.Name)  //  this is OK

@for(int i=0; i<Model.Functions.Count; i++)
{
    @Html.Partial(Model.Functions[i].Name, Model.Functions[i])
}

and the FunctionView may look like this

@model Function

@Html.TextBoxFor(m => m.Name)  //  the generated html element's name is just 'Name'

@for(int i=0; i < Model.Units.Count; i++)
{
    @Html.Partial(Model.Units[i].Name, Model.Units[i])
}

and this is UnitView

@model Unit

@Html.TextBoxFor(m => m.Name)  // the generated html element's name is just 'Name'

So my question is, what should I do the make the Name attribute correct?

Thanks a lot

4 Answers 4

1

The only change you need to make in the above code is to use Editor instead of partial view. So basically all you code will look similar to the following

@model License

@Html.TextBoxFor(m => m.Name) 
// Editor will take care of the repetition and u don't need to explicitly pass in the name
// Since the model already have the attribute
@Html.EditorFor(Model.Functions)

Then create your editor template folder, "EditorTemplates", under "Shared" folder and name your view file as "Function"

Do the same for Unit class and you will get what you want.

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

Comments

0

As @Jack said... you can do this using Editors instead of PartialViews.

BUT... if you really want to use PartialViews, you can do it, but the model to pass should be the top one (License). This way is similar of what David Jessee proposed, but splitting the one view in several.

1 Comment

I have only ONE Unit class, but need a lot of different views to render the unit. You're right, I need to pass the top one instead of the unit. Now I pass the License obj and the current function index and unit index to the partial view. It works. Thanks a lot.
0

Pardon me for guessing at the problem, but are you asking for the DisplayName attribute?

It will define how the html helpers display your field lables

public class License
{
    [DisplayName("License Name")]
    public string Name { get; set; }

    //  Other Properties

    public List<Function> Functions { get; set; }
}

public class Function
{
    [DisplayName("Fun Name")]
    public string Name { get; set; }

    //  Other Properties

    public List<Unit> Units { get; set; }
}

public class Unit
{
    [DisplayName("Unit Name")]
    public string Name { get; set; }

    //  Other Properties
}

be sure to have

using System.ComponentModel;

in your model code.

1 Comment

Hi Sam, thanks for your response. But that's not what I want. To make the html generated correct, for example, the input element for a unit should be like this <input type="text" name="Functions[0].Units[0].Name" /> but now the html is <input type="text" name="Name" /> .
0

If you want to be able to create all of the inputs for a complex object graph and have the entire graph be reconstituted by the model binder, the easiest way to approach it is to create a single view or partial view that renders the entire graph:

@for(int i=0;i<Functions.Length;i++){
    @for(int j=0;j<Units.Length;j++){

        @Html.EditorFor(Functions[i].Length[j].Unit)

    }
}

The other option would be to find a way to pass the index of your element to the partial views for each leaf on your object graph.

Granted, a lot of people dont like the idea of rendering a complex model inside of a single view. However, your other option is to make the smaller child views for Units, etc. be dependent on having additional data either injected or provided by the context. 6 of one, half dozen of the other. Just about every time I've done the "academically correct" approach of making exactly one view or partial view for each type in an object graph, I ended up with a whole bunch of views that were not reusable to begin with and the only advantage I got was the ability to say, "Look! Lots of small files.....that are totally dependent on each other...why did I do that?"

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.