views:

174

answers:

3

I can display a list of all customers and I can display a list of all orders and I would like to take this further.

I would like to render two partial views on the same page to show customer details and orders relating to that customer.

 <%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage< MyDemo.Models.CustomerAndOrdersViewModel >" %>

<% Html.RenderPartial("CustomerDetails", this.ViewData.Model.Customer); %>
<% Html.RenderPartial("CustomerOrders", this.ViewData.Model.Order); %>

I have created a viewmodel

public class CustomerAndOrdersViewModel
{
    public CustomerAndOrdersViewModel(Customer customer,
                        IEnumerable<Order> orders)
    {
        this.Customer = customer;
        this.Order = orders;
    }

    public Customer Customer { get; set; }
    public IEnumerable<Order> Order { get; set; }
}

And in my Customer Controller I have defined

    ICustomerRepository customerRepository;
    IOrderRepository orderRepository;

    public CustomersController()
        : this(new CustomerRepository())
    {
    }

    public CustomersController(ICustomerRepository repository)
    {
        customerRepository = repository;
    }

    public CustomersController(IOrderRepository repository)
    {
        orderRepository = repository;
    }

then I try to pass the CustomerAndOrdersViewModel to the details view

    public ActionResult Details(int id)
    {

        QuestionAndOrderViewModel viewdata = new CustomerAndOrdersViewModel(customerRepository.GetCustomer(id),
                                        orderRepository.FindAllOrders());
        return View(viewdata);
    }

But I am receiving the error "Object reference not set to an instance of an object" for orderRepository.

Where I am going wrong?

A: 

You are getting errors in the partial view, so all the code in the controllers is irrelevant. You need to see what is exactly contained in your Model, and if you are passing the right model to your partial view. Debug it and break at the RenderPartial call, then inspect the model, and review your partial view to see if you are passing the right values.

Palantir
+5  A: 

Your controller's constructors only take one argument, each, and you're attempting to use both values in the same instance.

You could do, for example:

ICustomerRepository customerRepository;
IOrderRepository orderRepository;

public CustomersController()
    : this(new CustomerRepository(), new OrderRepository())
{
}

public CustomersController(
    ICustomerRepository customerRepository, 
    IOrderRepository orderRepository)
{
    this.customerRepository = customerRepository;
    this.orderRepository = orderRepository;
}
Craig Stuntz
Could you please tell me how to resolve this?
Nicholas Murray
Have you tried the code sample I gave you? Incidentally, thank you for posting as much code as you did; it made the problem easy to spot.
Craig Stuntz
You can resolve it by using Craig's code, as his is exactly the same as mine, and mine never fails, of course ;-)
Razzie
I dunno. I think your positioning of curly braces might be a bit nicer. :)
Craig Stuntz
Cheers Craig and Razzie! Got it working now, lifted up that bug and guess what? more of them underneath, but I've stamped on all of them (for now).
Nicholas Murray
+1  A: 

Well, the controller factory calls the default controller, so this constructor is called:

public CustomersController() : this(new CustomerRepository())
{
}

Notice that you're only passing a CustomerRepository object, not a rolerepository. So change your code to:

ICustomerRepository customerRepository;
IOrderRepository orderRepository;

public CustomersController() : this(new CustomerRepository(), new OrderRepository())
{}

public CustomersController(ICustomerRepository customerRepository, IOrderRepository orderRepository)
{
  this.customerRepository = customerRepository;
  this.orderRepository = orderRepository;
}
Razzie