3

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.

halfer
  • 19,824
  • 17
  • 99
  • 186
mmssaann
  • 1,507
  • 6
  • 27
  • 55
  • To use code of one Project in another, take a look at [this](http://stackoverflow.com/questions/1116465/how-do-you-share-code-between-projects-solutions-in-visual-studio) possible dublicate. – Drasive Jun 12 '13 at 06:35

2 Answers2

2

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>
Ohlin
  • 4,068
  • 2
  • 29
  • 35
  • Can you please share your views here?My models are in my PartyBiz project,we use repositories to get the models thats not a problem though.I want to know how we are invoking the controller exists in second project.thanks a lot for trying.. – mmssaann Jun 12 '13 at 07:55
  • How is it with namespaces? Are you able to change the namespaces of your model and controller in the PartyBiz project so they are the same as the d2admin project? – Ohlin Jun 12 '13 at 08:06
  • I've now verified that the second project (PartyBiz) doesn't need the same namespace as the first project (d2admin). So you can forget my talk about namespaces. So the model and controller (in the second project) I gave the namespace PartyBiz and the views (in the first project) I updated so they would reference the new PartyBiz namespace...I'll update my example codes above as well in a few secs... – Ohlin Jun 12 '13 at 08:18
  • 1
    Ok, now the example codes above are updated to use the PartyBiz namespace. Note that nothing in d2admin uses the PartyBiz namespace, it only references to that namespace since the PartyBiz namespace is being used in the PartyBiz project. – Ohlin Jun 12 '13 at 08:27
  • thanks a lot for trying this, I am still trying this, my models are in PartyBiz.Models.Objects namespace, my controllers are in PartyWeb.Controllers namespace, my views are in d2admin project. do I need to import the controller namespace in views? – mmssaann Jun 12 '13 at 08:42
  • You need to add a reference to the PartyBiz project. Your views can then use `@using PartyBiz.Models.Objects` to add the namespace. – Ohlin Jun 12 '13 at 08:52
  • PartyBiz project in d2admin ?? – mmssaann Jun 12 '13 at 08:58
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/31635/discussion-between-mmssddff-and-ohlin) – mmssaann Jun 12 '13 at 09:00
  • I was a bit unclear there. The views in d2admin that work against the models in PartyBiz need to be able to find the PartyBiz objects, as I'm writing in the example code: `@model IEnumerable`. This can also be written as: `@using PartyBiz.Models` and then `@model IEnumerable` – Ohlin Jun 12 '13 at 09:01
  • Sorry may be i have not explained you clearly.My controls are in PartyWeb.Controllers.Internal folder, modle are in PartyBiz and views are in d2admin.When I run d2admin project, I should be able to run the controller exists in PartyWeb and this controller is responsible to fetch data from PartyBiz. I want to see the breakpoint hits the controller in PartyWeb and fetches data and gives to view in d2admin. – mmssaann Jun 12 '13 at 09:21
  • Did you see my suggestion in the chat room regarding adding the namespace to the route config? That might help as well... – Ohlin Jun 12 '13 at 09:24
  • Thank you for the help.. it is indeed hitting the controller of other project. The problem was - I have set the specific page to the controller exists in same project, I have changed it to the one in different projet, and added the project reference as you said and everything is working. Thank you very much for all the help.. – mmssaann Jun 12 '13 at 09:40
1

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.
    }
}
Daniel Siebert
  • 368
  • 3
  • 12