Search code examples
c#asp.net-mvcasp.net-mvc-5asp.net-mvc-viewmodel

add item base on other item id in one to many relation


I have this razor view that contain a few items base on some condition , I need to add a comment to any of the item (just like comment here in SO). trying to pass the id to a different form didn't work , this is what I have done but i guess it's the wrong approach . so far I have this : display the review according to user (parameter)

     public async Task<ActionResult> ReviewAbout(int? id)
    {
        var profilec = await db.profile.FindAsync(id);

        IEnumerable<ReviewViewModel> viewModel = from review in db.reviews.OrderBy(d => d.Created)
                                                 .Include(s => s.subject).Where(m => m.subject.MemberID == profilec.MemberID)
                                                 .Include(r => r.Writer)
                                                 join comment in db.Comments
                                                 on review.ReviewId equals comment.ReviewId into joinedReviewComment
                                                 select new ReviewViewModel
                                                 {
                                                     //parameters
                                                     ReviewId = review.ReviewId,

                                                     Comments = joinedReviewComment.Select(c => new CommentViewModel
                                                     {
                                                         CommentBody = c.CommentBody,
                                                         CommentGBU = c.CommentGBU,
                                                         anonymous = c.anonymous,

                                                         CommentsWriterName = c.CommentsWriterName
                                                     }).ToList(),
                                                 };

        return View(viewModel.ToList());
    }

in the view

    @model IList<MyWebSite.ViewModels.ReviewViewModel>
@for (int i = 0; i < Model.Count(); i++)
{
    @Html.DisplayFor(x => x[i].ReviewId)

    @Html.HiddenFor((x => x[i].ReviewId))

    @Html.ActionLink("comment", "AddComent", new { id = @Html.DisplayFor(x => x[i].ReviewId) })


    @for (var j = 0; j < Model[i].Comments.Count; j++)
    {
    }

}

I was trying to pass id to the view and to get the the the post controller look like this :

  public async Task <ActionResult > AddComent(Comments commnets )
    {


        //commnets.ReviewId = commnets.ReviewId;
        //commnets.ReviewId = commnets.review.ReviewId;
        //commnets.ReviewId = commnets.ReviewId;

        if (ModelState.IsValid)
        {
            db.Comments.Add(commnets);
            await db.SaveChangesAsync();
            return RedirectToAction("index");
        }
        return View(commnets);
    }

but, no luck, what it the best practices to do it ?


Solution

  • The problem is that AddComent method waits Comments model and your View posts ReviewViewModel. So, there is two options for workaround:

    1. If you just pass the id value use the following method and then use the same parameter name in the AddComent method as shown below:

    View:

    @Html.ActionLink("Comment", "AddComent", new { comment = item.ID }) 
    

    Controller:

    public async Task <ActionResult> AddComent(Comment comment)
    {
        ...
    }
    

    2) You can pass the ViewModel to the Controller and then try Mapping ViewModel to DomainModel as shown below:
    public async Task <ActionResult > AddComent(IEnumarable<ReviewViewModel> reviews)
    {
        if (ModelState.IsValid)
        {
    
            //Mapping ViewModel to DomainModel (Review > ReviewViewModel)
            var viewModel = new ReviewViewModel();
            AutoMapper.Mapper.CreateMap<Review , ReviewViewModel>();
            AutoMapper.Mapper.Map(model, viewModel);
            //
            db.Comments.Add(model);
            await db.SaveChangesAsync();
            return RedirectToAction("index");
        }
        return View(model);
    }
    

    For more information visit http://automapper.org/.