-1

I was trying to follow this question, Posting to a list<modeltype> MVC3, but I was running into a roadblock.

I want to display the full contents of a table, allow editing to that table, then submit it back to controller to save edits.

Specifically, the error I'm getting here is on Model.ClonePosts.Count:

'IEnumerable' does not contain a definition for 'ClonePosts' and no accessible extension method 'ClonePosts' accepting a first argument of type 'IEnumerable' could be found

Aside from that immediate problem, I'm not sure that have the binding correct. Will changes made in the View get posted correctly?

Thank you in advance

Model:

public class ClonePost
{
    [Key]
    public int id { get; set; }
    [Required]
    public string PostNumber { get; set; }
    [Required]
    public string Type { get; set; }
    [Required]
    public int ItemNumber { get; set; }
    public string ItemData { get; set; }
    public int ItemSelected { get; set; }
}

View model:

public class ReviewCloneVM
{
    public List<ClonePost> ClonePosts { get; set; }
}

View:

@model IEnumerable<AURA.ViewModels.ReviewCloneVM>

<h1>ReviewClone</h1>
<table class="table">
    @*foreach (var item in Model)*@
@for (int i = 0; i < Model.ClonePosts.Count; i++) {
    <tr>
        <td>
            @Html.EditorFor(x => x.ClonePosts[i].PostNumber)
        </td>
        <td>
            @Html.EditorFor(x => x.ClonePosts[i].ItemNumber)
        </td>
        <td>
            @Html.EditorFor(x => x.ClonePosts[i].ItemData)
        </td>
        <td>
            @Html.EditorFor(x => x.ClonePosts[i].ItemSelected)
        </td>
        <td>
            <input type="submit" value="Clone" />
        </td>
    </tr>
}
</tbody>
</table>

Controller:

    public async Task<IActionResult>ReviewClone(string zero = "230323-0")
    {
        ...
        // now call up the full table for review and edit
        var cloned = _context.ClonePosts.OrderByDescending(m => m.PostNumber);

        return View(await cloned.ToListAsync());
    }

    [HttpPost]
    public async Task<IActionResult>ReviewClone(ReviewCloneVM reviewCloneVM)
    {
        try
        {
            // other stuff
            return RedirectToAction("PostDetail", "Post", new { zero = "230323-0" });
        }
        catch
        {
            return View(reviewCloneVM);
        }
    }
2
  • I'm not sure why you use @model IEnumerable<AURA.ViewModels.ReviewCloneVM> instead of @model AURA.ViewModels.ReviewCloneVM in your view? Commented Mar 23, 2023 at 5:23
  • @NickFleetwood You need to assign your ClonePosts to the DB result. Check updated answer Commented Mar 23, 2023 at 6:08

2 Answers 2

1

You need to change your Model type from @model IEnumerable<AURA.ViewModels.ReviewCloneVM> to AURA.ViewModels.ReviewCloneVM and then access the ClonePosts from the Model :

@model AURA.ViewModels.ReviewCloneVM

<h1>ReviewClone</h1>
<table class="table">
  @if(Model !=null)
  {
      @*foreach (var item in Model)*@
      for (int i = 0; i < Model.ClonePosts.Count; i++) 
      {
        <tr>
            <td>
                @Html.EditorFor(x => x.ClonePosts[i].PostNumber)
            </td>
            <td>
                @Html.EditorFor(x => x.ClonePosts[i].ItemNumber)
            </td>
            <td>
                @Html.EditorFor(x => x.ClonePosts[i].ItemData)
            </td>
            <td>
                @Html.EditorFor(x => x.ClonePosts[i].ItemSelected)
            </td>
            <td>
                <input type="submit" value="Clone" />
            </td>
        </tr>
     }    
  }   
</tbody>
</table>

Your Controller method will be:

public async Task<IActionResult>ReviewClone(string zero = "230323-0")
{
    ...
    ReviewCloneVM model=new ReviewCloneVM();
    // now call up the full table for review and edit
    var cloned = _context.ClonePosts.OrderByDescending(m => m.PostNumber);
    model.ClonePosts =await cloned.ToListAsync();
    return View(model);
}
Sign up to request clarification or add additional context in comments.

Comments

0

In your View, You need to use

@model AURA.ViewModels.ReviewCloneVM

as the model, So try to change your code like:

Controller

public async Task<IActionResult> ReviewClone(string zero = "230323-0")
        {
            
        //now call up the full table for review and edit
            var cloned =  _context.ClonePosts.OrderByDescending(m => m.PostNumber).ToList();
            ReviewCloneVM vm = new ReviewCloneVM()
            {
                ClonePosts = cloned,
            };
            return View(vm);
        }

View

@model AURA.ViewModels.ReviewCloneVM

<h1>ReviewClone</h1>
<form method="post">
    @*foreach (var item in Model)*@
    @for (int i = 0; i < Model.ClonePosts.Count; i++)
    {
        <tr>
            <td>
                @Html.EditorFor(x => x.ClonePosts[i].PostNumber)
            </td>
            <td>
                @Html.EditorFor(x => x.ClonePosts[i].ItemNumber)
            </td>
            <td>
                @Html.EditorFor(x => x.ClonePosts[i].ItemData)
            </td>
            <td>
                @Html.EditorFor(x => x.ClonePosts[i].ItemSelected)
            </td>
            
        </tr>
        <br />
    }

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

Demo:

enter image description here

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.