Link to home
Start Free TrialLog in
Avatar of Intelli-Seeker
Intelli-SeekerFlag for United States of America

asked on

ActionLink to different model in ASP.NET MVC 5

I have a CustomersController and MeetingsController. I want a link at the bottom that will redirect to the "Create" view based on the Id field of the Meeting Model. The way I have it written now, it redirects to the Create view in the MeetingsController, but does not save to the Id of the Customer.

(Note: I realize there is a lot of superfluous code. This is a work in progress and much of the code was created by default with the entity framework scaffolding.)

Here is the Customer Details view code. The Html.ActionLink is at the bottom of the page. That is where I want to redirect to the Create Meeting page but I want that meeting to be attached to the customer that is in the details view. I can post screenshots of the webpages if the community thinks that would be helpful.

Customer "Details" view:
@model WoodTrustCRM.Models.Customer

@{
    ViewBag.Title = "Details";
}

<h2>Customer Details</h2>

<div>
    <dl class="dl-horizontal">
        <dt>
            @Html.DisplayNameFor(model => model.SystemOfRecordId)
        </dt>

        <dd>
            @Html.DisplayFor(model => model.SystemOfRecordId)
        </dd>

        <dt>
            @Html.DisplayNameFor(model => model.Relationship)
        </dt>

        <dd>
            @Html.DisplayFor(model => model.Relationship)
        </dd>

        <dt>
            @Html.DisplayNameFor(model => model.Tin)
        </dt>

        <dd>
            @Html.DisplayFor(model => model.Tin)
        </dd>

        <dt>
            @Html.DisplayNameFor(model => model.Name)
        </dt>

        <dd>
            @Html.DisplayFor(model => model.Name)
        </dd>

        <dt>
            @Html.DisplayNameFor(model => model.status_id)
        </dt>

        <dd>
            @Html.DisplayFor(model => model.status_id)
        </dd>

        <dt>
            @Html.DisplayNameFor(model => model.ConfidenceRating)
        </dt>

        <dd>
            @Html.DisplayFor(model => model.ConfidenceRating)
        </dd>

        <dt>
            @Html.DisplayNameFor(model => model.BankOfficer)
        </dt>

        <dd>
            @Html.DisplayFor(model => model.BankOfficer)
        </dd>

        <dt>
            @Html.DisplayNameFor(model => model.TrustOfficer)
        </dt>

        <dd>
            @Html.DisplayFor(model => model.TrustOfficer)
        </dd>

        <dt>
            @Html.DisplayNameFor(model => model.IsBusinessCustomer)
        </dt>

        <dd>
            @Html.DisplayFor(model => model.IsBusinessCustomer)
        </dd>

    </dl>
    <br />
    <h2>Customer Meeting Information</h2>
    <hr />
@*Add meeting details to customer details page - review https://docs.microsoft.com/en-us/aspnet/mvc/overview/getting-started/database-first-development/customizing-a-view*@
<table class="table">
    <tr>
        <th>
            Interaction Date
        </th>
        <th>
            Notes
        </th>
        <th>
            Bank Officer
        </th>
        <th>
            Trust Officer
        </th>
        <th>
            Details
        </th>
    </tr>
    @foreach (var item in Model.Meeting)
    {
        <tr>
            <td>
                @Html.DisplayFor(modelItem => item.InteractionDate)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Notes)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.BankOfficer)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.TrustOfficer)
            </td>
            <td>
                @Html.ActionLink("Details", "Details", "Meetings", new { id = item.Id }, null)
                
            </td>
        </tr>
    }
</table>
</div>
<div>
    <input type="button" value="Print this page" onclick="window.print()"><br /><br />
</div>
<div>
    <h4>@Html.ActionLink("Create New Meeting", "Create", "Meetings", new { id = Model.Id }, null) | @Html.ActionLink("Edit Customer", "Edit", new { id = Model.Id })   | @Html.ActionLink("Back to Search", "Index")</h4>
    
</div>

Open in new window


This is the "CustomersController":
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Net;
using System.Web;
using System.Web.Mvc;
using WoodTrustCRM.Models;

namespace WoodTrustCRM.Controllers
{
    public class CustomersController : Controller
    {
        private WoodTrustCRMEntities db = new WoodTrustCRMEntities();

        // GET: Home - this is a view I created
        public ActionResult Home()
        {
            return View();
        }

        ////default GET: Customers
        //public ActionResult Index()
        //{
        //    return View(db.Customer.ToList());
        //}

        //GET: Customers
        public ActionResult Index(string searchBy, string search)
        {
            if (searchBy == "Name")
            {
                return View(db.Customer.Where(x => x.Name.StartsWith(search)).ToList());
            }
            else
                return View(db.Customer.Where(x => x.Tin.StartsWith(search)).ToList());
        }

        ////GET: Customers - work in progress - more advanced filter
        //public ViewResult Index(string sortOrder, string searchString)
        //{
        //    ViewBag.NameSortParm = String.IsNullOrEmpty(sortOrder) ? "name_desc" : "";
        //    var name = from Name in db.Customer
        //                    select Name;
        //    if (!String.IsNullOrEmpty(searchString))
        //    {
        //        name = name.Where(n => n.Name.Contains(searchString));
        //    }
        //    switch (sortOrder)
        //    {
        //        case "name_desc":
        //            name = name.OrderByDescending(n => n.Name);
        //            break;
        //        //case "TIN":
        //        //    customers = customers.OrderBy(c => c.Tin);
        //        //    break;
        //        default:
        //            name = name.OrderBy(n => n.Name);
        //            break;
        //    }
        //    return View(db.Customer.ToList());

        //}

        //// DEFAULT GET: Customers/Details
        //public ActionResult Details(int? id)
        //{
        //    if (id == null)
        //    {
        //        return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
        //    }
        //    Customer customer = db.Customer.Find(id);
        //    if (customer == null)
        //    {
        //        return HttpNotFound();
        //    }
        //    return View(customer);
        //}

        // Code GET: Customers/Details with meetings
        public ActionResult Details(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            Customer customer = db.Customer.Find(id);
            Meeting meeting = db.Meeting.Find(id);
            return View(customer);
        }

        // GET: Customers/Details/5

        //// GET: Customers and Meetings in one view using ViewBag - needs work
        //public ActionResult IndexViewBag()
        //{
        //    ViewBag.Message = "Welcome to my demo!";
        //    ViewBag.Meeting = GetMeeting();
        //    ViewBag.Customer = GetCustomer();
        //    return View();
        //}

        // GET: Customers/Create
        public ActionResult Create()
        {
            return View();
        }

        // POST: Customers/Create
        // To protect from overposting attacks, please enable the specific properties you want to bind to, for 
        // more details see https://go.microsoft.com/fwlink/?LinkId=317598.
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Create([Bind(Include = "Id,SystemOfRecordId,Relationship,Tin,Name,status_id,ConfidenceRating,BankOfficer,TrustOfficer,IsBusinessCustomer")] Customer customer)
        {
            if (ModelState.IsValid)
            {
                db.Customer.Add(customer);
                db.SaveChanges();
                return RedirectToAction("Index");
            }

            return View();
        }

        // GET: Customers/Edit/5
        public ActionResult Edit(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            Customer customer = db.Customer.Find(id);
            if (customer == null)
            {
                return HttpNotFound();
            }
            return View(customer);
        }

        // POST: Customers/Edit/5
        // To protect from overposting attacks, please enable the specific properties you want to bind to, for 
        // more details see https://go.microsoft.com/fwlink/?LinkId=317598.
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Edit([Bind(Include = "Id,SystemOfRecordId,Relationship,Tin,Name,status_id,ConfidenceRating,BankOfficer,TrustOfficer,IsBusinessCustomer")] Customer customer)
        {
            if (ModelState.IsValid)
            {
                db.Entry(customer).State = EntityState.Modified;
                db.SaveChanges();
                return RedirectToAction("Index");
            }
           return View(customer);
        }

        // GET: Customers/Delete/5
        public ActionResult Delete(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            Customer customer = db.Customer.Find(id);
            if (customer == null)
            {
                return HttpNotFound();
            }
            return View(customer);
        }

        // POST: Customers/Delete/5
        [HttpPost, ActionName("Delete")]
        [ValidateAntiForgeryToken]
        public ActionResult DeleteConfirmed(int id)
        {
            Customer customer = db.Customer.Find(id);
            db.Customer.Remove(customer);
            db.SaveChanges();
            return RedirectToAction("Index");
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                db.Dispose();
            }
            base.Dispose(disposing);
        }
    }
}

Open in new window


This is the Create view linked to the Meeting Model:
@model WoodTrustCRM.Models.Meeting

@{
    ViewBag.Title = "Create";
}

<h2>Create</h2>


@using (Html.BeginForm()) 
{
    @Html.AntiForgeryToken()
    
    <div class="form-horizontal">
        <h4>Meeting</h4>
        <hr />
        @Html.ValidationSummary(true, "", new { @class = "text-danger" })
        <div class="form-group">
            @Html.LabelFor(model => model.InteractionDate, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.InteractionDate, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.InteractionDate, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.Notes, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.Notes, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.Notes, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.approval_status_id, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.approval_status_id, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.approval_status_id, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.CustomerCallDecisionedBy, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.CustomerCallDecisionedBy, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.CustomerCallDecisionedBy, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.CustomerCallDecisionDate, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.CustomerCallDecisionDate, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.CustomerCallDecisionDate, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.BankOfficer, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.BankOfficer, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.BankOfficer, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.TrustOfficer, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.TrustOfficer, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.TrustOfficer, "", new { @class = "text-danger" })
            </div>
        </div>

        @*<div class="form-group">
            @Html.LabelFor(model => model.Customer, "Customer", htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.DropDownList("Customer", null, htmlAttributes: new { @class = "form-control" })
                @Html.ValidationMessageFor(model => model.Customer, "", new { @class = "text-danger" })
            </div>
        </div>*@

        <div class="form-group">
            @Html.LabelFor(model => model.Employee, "Employee", htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.DropDownList("Employee", null, htmlAttributes: new { @class = "form-control" })
                @Html.ValidationMessageFor(model => model.Employee, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.IsDeleted, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                <div class="checkbox">
                    @Html.EditorFor(model => model.IsDeleted)
                    @Html.ValidationMessageFor(model => model.IsDeleted, "", new { @class = "text-danger" })
                </div>
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.ConfidenceRating, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.ConfidenceRating, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.ConfidenceRating, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.IsReview, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                <div class="checkbox">
                    @Html.EditorFor(model => model.IsReview)
                    @Html.ValidationMessageFor(model => model.IsReview, "", new { @class = "text-danger" })
                </div>
            </div>
        </div>

        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="Create" class="btn btn-default" />
            </div>
        </div>
    </div>
}

<div>
    @Html.ActionLink("Back to List", "Index")
</div>

@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
}

Open in new window


This is the MeetingsController:
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Net;
using System.Web;
using System.Web.Mvc;
using WoodTrustCRM.Models;

namespace WoodTrustCRM.Controllers
{
    public class MeetingsController : Controller
    {
        private WoodTrustCRMEntities db = new WoodTrustCRMEntities();

        // GET: Meetings
        public ActionResult Index()
        {
            var meeting = db.Meeting.Include(m => m.Customer1).Include(m => m.Employee1);
            return View(meeting.ToList());
        }

        // GET: Meetings/Details/5
        public ActionResult Details(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            Meeting meeting = db.Meeting.Find(id);
            if (meeting == null)
            {
                return HttpNotFound();
            }
            return View(meeting);
        }

        // GET: Meetings/Create
        public ActionResult Create()
        {
            ViewBag.Customer = new SelectList(db.Customer, "Id", "SystemOfRecordId");
            ViewBag.Employee = new SelectList(db.Employee, "Id", "FirstName");
            return View();
        }

        // POST: Meetings/Create
        // To protect from overposting attacks, please enable the specific properties you want to bind to, for 
        // more details see https://go.microsoft.com/fwlink/?LinkId=317598.
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Create([Bind(Include = "Id,InteractionDate,Notes,approval_status_id,CustomerCallDecisionedBy,CustomerCallDecisionDate,BankOfficer,TrustOfficer,Customer,Employee,IsDeleted,ConfidenceRating,IsReview")] Meeting meeting)
        {
            if (ModelState.IsValid)
            {
                db.Meeting.Add(meeting);
                db.SaveChanges();
                return RedirectToAction("Index", "Customers");
            }

            ViewBag.Customer = new SelectList(db.Customer, "Id", "SystemOfRecordId", meeting.Customer);
            ViewBag.Employee = new SelectList(db.Employee, "Id", "FirstName", meeting.Employee);
            return View(meeting);
        }

        // GET: Meetings/Edit/5
        public ActionResult Edit(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            Meeting meeting = db.Meeting.Find(id);
            if (meeting == null)
            {
                return HttpNotFound();
            }
            ViewBag.Customer = new SelectList(db.Customer, "Id", "SystemOfRecordId", meeting.Customer);
            ViewBag.Employee = new SelectList(db.Employee, "Id", "FirstName", meeting.Employee);
            return View(meeting);
        }

        // POST: Meetings/Edit/5
        // To protect from overposting attacks, please enable the specific properties you want to bind to, for 
        // more details see https://go.microsoft.com/fwlink/?LinkId=317598.
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Edit([Bind(Include = "Id,InteractionDate,Notes,approval_status_id,CustomerCallDecisionedBy,CustomerCallDecisionDate,BankOfficer,TrustOfficer,Customer,Employee,IsDeleted,ConfidenceRating,IsReview")] Meeting meeting)
        {
            if (ModelState.IsValid)
            {
                db.Entry(meeting).State = EntityState.Modified;
                db.SaveChanges();
                return RedirectToAction("Index");
            }
            ViewBag.Customer = new SelectList(db.Customer, "Id", "SystemOfRecordId", meeting.Customer);
            ViewBag.Employee = new SelectList(db.Employee, "Id", "FirstName", meeting.Employee);
            return View(meeting);
        }

        // GET: Meetings/Delete/5
        public ActionResult Delete(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            Meeting meeting = db.Meeting.Find(id);
            if (meeting == null)
            {
                return HttpNotFound();
            }
            return View(meeting);
        }

        // POST: Meetings/Delete/5
        [HttpPost, ActionName("Delete")]
        [ValidateAntiForgeryToken]
        public ActionResult DeleteConfirmed(int id)
        {
            Meeting meeting = db.Meeting.Find(id);
            db.Meeting.Remove(meeting);
            db.SaveChanges();
            return RedirectToAction("Index");
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                db.Dispose();
            }
            base.Dispose(disposing);
        }
    }
}

Open in new window


This is a screenshot of the model: User generated image
SOLUTION
Avatar of Miguel Oz
Miguel Oz
Flag of Australia image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of Intelli-Seeker

ASKER

I changed my code in the controller and view It shows the customer ID in the URL, but the meeting is not saved to the customer. It is saved with the Customer "NULL" in the Meetings table.

User generated image
 

Does the HttpPost also need to be updated in either the MeetingsController or the CustomersController? This is the HttpPost in the MeetingsController.

[HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Create([Bind(Include = "Id,InteractionDate,Notes,approval_status_id,CustomerCallDecisionedBy,CustomerCallDecisionDate,BankOfficer,TrustOfficer,Customer,Employee,IsDeleted,ConfidenceRating,IsReview")] Meeting meeting)
        {
            if (ModelState.IsValid)
            {
                db.Meeting.Add(meeting);
                db.SaveChanges();
                return RedirectToAction("Index", "Customers");
            }

            ViewBag.Customer = new SelectList(db.Customer, "Id", "SystemOfRecordId", meeting.Customer);
            ViewBag.Employee = new SelectList(db.Employee, "Id", "FirstName", meeting.Employee);
            return View(meeting);
        }

Open in new window


Just a note on the Details view code that I posted originally - this view is based on the WoodTrustCRM.Models.Customer. I want the the ActionLink to create the Meeting in the Meetings table. I updated the code in the Details view as suggested (unless I missed something).

<div>
    <h4>@Html.ActionLink("Create New Meeting", "Create", "Meetings", new { customerId = Model.Id }, null) | @Html.ActionLink("Edit Customer", "Edit", new { id = Model.Id })   | @Html.ActionLink("Back to Search", "Index")</h4>
    
</div>

Open in new window


I also updated the GET request in the MeetingsController:

// GET: Meetings/Create
        public ActionResult Create(int customerId)
        {
            ViewBag.Customer = new SelectList(db.Customer, "Id", "SystemOfRecordId");
            ViewBag.Employee = new SelectList(db.Employee, "Id", "FirstName");
            return View();
        }

Open in new window

ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
I want to make sure I understand correctly. This is the current code for the create method in the CustomersController.

//GET: Customers/Create
        public ActionResult Create()
        {
            return View();
        }

Open in new window


You are suggesting changing that code to:
 public ActionResult Create(int customerId)
{
            ViewBag.Customer = new SelectList(db.Customer, "Id", "SystemOfRecordId"); //break point here
            ViewBag.Employee = new SelectList(db.Employee, "Id", "FirstName");
            return View();
}

Open in new window

Thanks for your assistance. You pointed me in the right direction.