Запутался в том, как контроллеры на самом деле сопоставляются с представлениями в этом случае

У меня есть эти два URL-адреса, которые я хочу сделать доступными для своих пользователей:

/Account/Orders   <- This would should be a grid of all orders.
/Account/Orders/132   <- This would show this particular order information.

Вот мои два ActionMethods:

[Authorize]
public ActionResult Orders(int id)
{
    using (var orderRepository = new EfOrderRepository())
    using (var accountRepository = new EfAccountRepository())
    {
        OrderModel model = new OrderModel();
        return View(model);
    }
}

[Authorize]
public ActionResult Orders()
{
    using (var orderRepository = new EfOrderRepository())
    using (var accountRepository = new EfAccountRepository())
    {            
        List<OrderModel> model = new List<OrderModel>();
        return View(model);
    }
}

Если мое представление Orders строго типизировано с OrderModel в качестве модели, метод действия Orders() не будет работать, так как мне нужно передать ему IEnumerable вместо одного объекта.

Что вы предлагаете в этом случае? Кажется, что это легко сделать, но у меня был очень длинный (продуктивный!) день, но я могу зайти так далеко.


person Only Bolivian Here    schedule 07.04.2012    source источник
comment
Используйте метод редактирования (или списка) и метод индекса, чтобы быть немного больше в «стандартной» сфере MVC.   -  person Adam Tuliper - MSFT    schedule 07.04.2012


Ответы (3)


Пара вариантов:

1) Сначала настройте свои маршруты с наиболее конкретным маршрутом.

MapRoute("first", "/Accounts/Orders/{id}" ....
           controller="mycontroller" action="details"
MapRoute("second", "/Accounts/Orders .....
           controller="mycontroller" action="summary"

2) Вместо маршрутов есть два метода get с разными сигнатурами:

public ActionResult Index()
{
}

[ActionName("Index")] public ActionResult IndexDetails(int id) { }

Маршрутизация должна соответствовать

person mmcconnell1618    schedule 07.04.2012
comment
Чувак, я устал прошлой ночью... настройка маршрутов - очевидное решение этой проблемы. Спасибо, что снова запустили мой мозг. :) - person Only Bolivian Here; 07.04.2012

Предполагая, что вы используете маршруты по умолчанию, ваш второй метод Order никогда не будет вызываться. Маршрут заполнит отсутствующий параметр id нулевым значением, если оно не указано, и попытается вызвать перегрузку с параметром id.

Вы можете изменить свои маршруты или сделать что-то еще, чтобы попытаться обойти это, но более быстрый вариант — просто работать в системе маршрутизации:

public ActionResult Orders(int id = -1)
{
  return id == -1 ? this.OrdersSummary() : this.OrdersDetail(id);
}

private ActionResult OrdersSummary()
{
  var model = new SummaryModel();
  // fill in model;
  return this.View("OrdersSummary", model);
}

private ActionResult OrdersDetail(int id) 
{
  var model = new DetailModel();
  // fill in model;
  return this.View("OrderDetail", model);
}    
person Michael Edenfield    schedule 07.04.2012
comment
Вы также можете использовать обнуляемый int (int? id) и проверить id.HasValue вместо принудительного -1. - person Nick Bork; 07.04.2012

У вас может быть два разных взгляда. Один для сетки и один для деталей заказа.

Затем вы можете вызывать их так:

return View("OrderGrid", Orders); // for grid

return View("OrderDetail", Order); // for detail
person Moon    schedule 07.04.2012
comment
Я получаю сообщение об ошибке еще до того, как эта область кода будет достигнута, в нем говорится, что только необязательный параметр должен быть нулевым. Это означает, что при посещении Accounts/Orders я обращаюсь к неправильному методу ActionMethod. - person Only Bolivian Here; 07.04.2012