Call controller of another project from view in MVC4

12,080

Solution 1

I found your problem interesting and decided to test for myself. I created two MVC projects (but one of them could be a class library as well, I was lazy though). The first MVC project became the main one with routes and views, the second project got the model and the controller. It worked like a charm from start and here is how I did it.

I created the model in the second project, named Car in my example (the name UsersContext is left from the default files because I wanted to change as little as possible).

namespace PartyBiz.Models
{
    public class UsersContext : DbContext
    {
        public UsersContext()
            : base("DefaultConnection")
        {
        }

        public DbSet<Car> Cars { get; set; }
    }

    [Table("Cars")]
    public class Car
    {
        [Key]
        [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
        public int CarId { get; set; }
        public string CarName { get; set; }
    }
}

I then built the project and created a controller with EF connections to Car (by right clicking on the Controller folder and select MVC controller with read/write actions and views, using Entity Framework)

The controller looked like this when done (many lines have been removed to keep the example short)

namespace PartyBiz.Controllers
{
    public class CarController : Controller
    {
        // UsersContext is a left over from the default MVC project
        private UsersContext db = new UsersContext();

        public ActionResult Index()
        {
            return View(db.Cars.ToList());
        }

        // Many other actions follows here...
    }
}

The views that were created in the second project (PartyBiz) I copied over to the first project (d2admin) by drag and drop. I then deleted the views from the second project to make sure they weren't used there.

I also had to add a reference from the first project (with the views) to the second project (model and controller). After that it worked just fine to run the first project.

I continued to enable migrations in the model-controller-project and got a database connection without any problems. I could see that the controller managed to save data even though it was located in a different project.

I hope this can help you on the way...

EDIT: Using the following code in the views from the first project (d2admin) worked fine even though the Car controller referred to exists in the second project. This link was used in the home (controller) / index (view) in the first project.

@Html.ActionLink("Go to the cars", "Index", "Car")

EDIT2: This is the index view for the Car controller. The view is in d2admin and is referencing a controller in the PartyBiz project.

@model IEnumerable<PartyBiz.Models.Car>

@{
    ViewBag.Title = "Index";
}

<h2>Index</h2>

<p>
    @Html.ActionLink("Create New", "Create")
</p>
<table>
    <tr>
        <th>
            @Html.DisplayNameFor(model => model.CarName)
        </th>
        <th></th>
    </tr>

@foreach (var item in Model) {
    <tr>
        <td>
            @Html.DisplayFor(modelItem => item.CarName)
        </td>
        <td>
            @Html.ActionLink("Edit", "Edit", new { id=item.CarId }) |
            @Html.ActionLink("Details", "Details", new { id=item.CarId }) |
            @Html.ActionLink("Delete", "Delete", new { id=item.CarId })
        </td>
    </tr>
}
</table>

Solution 2

I acknowledge this is an old question with an already accepted answer; however, I ran into the same problem and was able to solve it and would like to share my experience.

From what I understand the following things are true:

  • d2admin is the code that handles the front end of the web site, and the controllers are used to drive the views and/or view models.
  • PartyWeb is used as an API at a domain level to interact with some datasource.
  • OrganizationController is the controller you're using to get data from the datasource to the d2admin project (and vice-versa)

With all of that in mind, arise the power of partial views!

Let's use the very simple View that would be located in d2admin/Views/SomeController.cshtml where SomeController is the folder that reflects the controller associated with these views.

<h3>A Very Basic View</h3>

@Html.Partial("_SomePartialView", OrganizationController.GetOrganizations())

Notice that this view has no model, and calls a partial and it's model is populated right there... and that's it! Now how would we write _SomePartialView.cshtml?

We will put it in the d2admin/Views/Shared folder, so the full path would be: d2admin/Views/Shared/_SomePartialView.cshtml. The file will look like

@model IEnumerable<PartyWeb.Models.Organization>

<div>
   @foreach(var o in Model){
       @Html.DisplayFor(modelItem => item.Id)
       @Html.DisplayFor(modelItem => item.Name)
       <br/>
   }
</div>

As we can see this view will display some basic info assuming the following is our model found at PartyWeb/Models/Organization.cs

public class Organization
{
    public int Id {get; set;}
    public string Name {get; set;}
    // some additional properties
}

and for the final bit of magic... Within OrganizationController.cs we need to add the static action that will enable us to get the data to bind to our partial view's model. So we would add the following:

public class OrganizationController : ApiController
{
    // Some Other Actions

    [HttpGet]
    public static List<Organization> GetOrganizations()
    {
        var dataSource = GetDataSource(); // Some Method that exposes the datasource
        return ReadAllOrganizations(dataSource); // Some method that allows us to read all of the organiztions from the dataSource, i.e. some sql that executes against a database.
    }
}
Share:
12,080
mmssaann
Author by

mmssaann

Being eco-friendly..loves planting

Updated on June 05, 2022

Comments

  • mmssaann
    mmssaann almost 2 years

    I have two projects, d2admin and PartyWeb.

    d2admin is the actual UI, it will have all necessary css, js and views etc., and also controllers if required.

    PartyWeb is having controllers for each table in Party.

    Say I have a table called - Organization. This table's controller will be in PartyWe/Controllers folder.

    I will have the views in d2admin.

    Now my problem is how can I invoke the OrganizationController exists in PartyWeb from the view Organization.cshtml exists in d2admin?

    I tried with Html.RenderAction, this is working for the controllers exists in same, when I call the controller of diff project I am getting - missing method exception.