1

I have setup a basic model binder by passing in a list to a view and running:

Controller:

[Authorize]
public ActionResult AddTracks(int id)
{
    TrackRepository trackRepository = new TrackRepository();
    //ShowTrackAssociationHelper showTrack = new ShowTrackAssociationHelper();

    //showTrack.tracks = trackRepository.GetAssociatedTracks(id).ToList();
    //showTrack.show = showRepository.GetShow(id);
    TracksViewModel tracksModel = new TracksViewModel();
    tracksModel.Tracks = trackRepository.GetAssociatedTracks(id);

    ViewBag.ShowID = id;
    return View(tracksModel);


}

View:

 @model BluesNetwork.Models.TracksViewModel
 @Html.EditorFor(model => model.Tracks, "TrackEditor")

TracksView Model:

public class TracksViewModel
{

    public IEnumerable<Track> Tracks  { get; set; }

}

TackEditor:

 @model BluesNetwork.Models.Track
@using (Html.BeginForm())
{
    @Html.ValidationSummary(true)


        @Html.HiddenFor(model => model.TrackID)
        @Html.HiddenFor(model => model.ShowID)

        <div class="editor-label">
            @Html.LabelFor(x => x.Title)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Title)
            @Html.ValidationMessageFor(model => model.Title)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.TrackNumber)
        </div>
        <div class="editor-field">
            @Html.TextBoxFor(model => model.TrackNumber, new { maxlength = 2 })
            @Html.ValidationMessageFor(model => model.TrackNumber)
        </div>
            @Html.HiddenFor(model => model.HQFileID)
            @Html.HiddenFor(model => model.LQFileID)

        <div class="editor-label">
            @Html.LabelFor(model => model.InternalRating)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.InternalRating)
            @Html.ValidationMessageFor(model => model.InternalRating)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.License)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.License)
            @Html.ValidationMessageFor(model => model.License)
        </div>


        <div class="editor-label">
            @Html.LabelFor(model => model.LicenseNumber)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.LicenseNumber)
            @Html.ValidationMessageFor(model => model.LicenseNumber)
        </div>

        <input type="submit" value="Save" />





}

At first I was getting:

Which gives me output as such on each input:

name="[0].ShowID"

however I wanted it to be:

name="track[0].ShowID"

I've seen examples/tutorials that show output like this but they don't go into detail about it.

After following RPM1984's advice and making the changes I got the error:

The model item passed into the dictionary is of type 'System.Data.Objects.ObjectQuery`1[BluesNetwork.Models.Track]', but this dictionary requires a model item of type 'BluesNetwork.Models.Track'.

Thank you in advance for all help

At

2 Answers 2

2

Not sure what you mean by "I have setup a basic model binder". That doesn't look like a model binder, that looks like a template or partial view.

Anyway, moving on....

You should have a ViewModel like this:

public class TracksViewModel
{
    public IEnumerable<Track> Tracks { get; set; }
}

Main View:

@model TracksViewModel
@Html.EditorFor(model => model.Tracks)

Editor Template:

@model Track
@Html.EditorFor(model => model.ShowId)

No loops, no magic strings. Nice.

Which will render HTML like this:

<input type="text" name="tracks[0].ShowId" />
<input type="text" name="tracks[1].ShowId" />
<input type="text" name="tracks[2].ShowId" />

Which is what you want, right?

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

10 Comments

Thats what I want, but when I try your solution I get: The model item passed into the dictionary is of type 'System.Data.Objects.ObjectQuery`1[BluesNetwork.Models.Track]', but this dictionary requires a model item of type 'BluesNetwork.Models.Track'.
@dreadlocks1221 - show the code for your controller action method which returns this view. Looks like your returning the EF query, when you should be materializing the query first, e.g var model = new TracksViewModel { Tracks = db.Tracks.ToList() }; return View(model);. You should probably also use a ViewModel for Track as well, but one step at a time.
@dreadlocks1221 - yep, i'm guessing trackRepository.GetAssociatedTracks(id) returns either IQueryable or IEnumerable. You need to fire the query in your controller, like i said above.
So then why doesn't the track view model require list instead of Ienumerable?
@dreadlocks1221 - List<T> implements IEnumerable<T>. Did you just try what i said?
|
0

Basically if you want to change the names you will need to bust out some JavaScript or roll your own partial view.

Note that changing id's and names of bound fields is, generally speaking, a poor idea because this will break the baked in binding of your ViewModel. Do you really need to change the name?

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.