Передача даних на головну сторінку в ASP.NET MVC


102

Який спосіб передачі даних на головну сторінку (за допомогою ASP.NET MVC) без порушення правил MVC?

Особисто я вважаю за краще кодувати абстрактний контролер (базовий контролер) або базовий клас, який передається всім переглядам.


1
Я написав керівництво про те, як мені це вдалося: britishdeveloper.co.uk/2010/06/… повинен допомогти
BritishDeveloper

Відповіді:


77

Якщо ви віддаєте перевагу вашим представленням сильно набраних класів даних перегляду, це може вам підійти. Інші рішення, ймовірно, більш правильні, але це приємний баланс між дизайном та практичністю IMHO.

Основна сторінка приймає сильно набраний клас даних перегляду, що містить лише релевантну їй інформацію:

public class MasterViewData
{
    public ICollection<string> Navigation { get; set; }
}

Кожен перегляд, що використовує цю головну сторінку, приймає сильно набраний клас даних перегляду, що містить його інформацію та походить від даних перегляду головних сторінок:

public class IndexViewData : MasterViewData
{
    public string Name { get; set; }
    public float Price { get; set; }
}

Оскільки я не хочу, щоб окремі контролери нічого знали про збирання даних головних сторінок, я інкапсулюю цю логіку на фабрику, яка передається кожному контролеру:

public interface IViewDataFactory
{
    T Create<T>()
        where T : MasterViewData, new()
}

public class ProductController : Controller
{
    public ProductController(IViewDataFactory viewDataFactory)
    ...

    public ActionResult Index()
    {
        var viewData = viewDataFactory.Create<ProductViewData>();

        viewData.Name = "My product";
        viewData.Price = 9.95;

        return View("Index", viewData);
    }
}

Спадщина відповідає майстру, щоб добре переглядати відносини, але коли мова заходить про надання реквізитів / елементів керування користувачами, я складу їх дані перегляду в дані перегляду сторінок, наприклад

public class IndexViewData : MasterViewData
{
    public string Name { get; set; }
    public float Price { get; set; }
    public SubViewData SubViewData { get; set; }
}

<% Html.RenderPartial("Sub", Model.SubViewData); %>

Це лише приклад коду і не призначений для компіляції як є. Розроблений для ASP.Net MVC 1.0.


4
Це метод, рекомендований Скоттом Ґетері, тому мені доведеться погодитися.
Саймон Фокс

@Simon Fox - отримав посилання на рекомендацію скоттгу? Не вдалося його знайти.
Оріп


Вибачте. Мало проблем з розумінням частини цього. Конструктору для контролера передається екземпляр IViewDataFactory, але система очікує безпараметричного конструктора. Я також не знайомий із цим синтаксисом C # (конкретно "MasterViewData, new ()") для інтерфейсу. Може хтось, будь ласка, пояснить це чи вкаже мені на хороший ресурс. Дякую.
Джейсон

5
Мені подобається працювати з сильно набраними моделями, але я не є великим прихильником з'єднання основних даних з усіма іншими моїми моделями та діями. Трохи запізнюючись у цю нитку, я опублікував свій підхід до майстерних даних, що забезпечує більш валість.
Тодд Меньє

59

Я вважаю за краще розбивати керовані даними фрагменти головного виду на партії та рендерінг їх за допомогою Html.RenderAction . Це має ряд чітких переваг перед підходом до успадкування популярної моделі перегляду:

  1. Дані головного перегляду повністю відокремлюються від "звичайних" моделей перегляду. Це склад над успадкуванням і призводить до більш вільно пов'язаної системи, яку легше змінити.
  2. Моделі головного перегляду побудовані повністю окремим дією контролера. "Регулярні" дії не повинні турбуватися з цього приводу, і немає потреби у фабриці даних перегляду, що здається надто складним на мій смак.
  3. Якщо ви використовуєте такий інструмент, як AutoMapper, для відображення вашого домену на моделях перегляду, вам буде легше налаштувати, оскільки ваші моделі перегляду будуть більше нагадувати ваші доменні моделі, коли вони не успадковують дані головного перегляду.
  4. За допомогою окремих методів дій для головних даних ви можете легко застосувати кешування вихідних даних до певних регіонів сторінки. Зазвичай головні перегляди містять дані, які змінюються рідше, ніж вміст основної сторінки.

3
+1. Ще одна перевага полягає в тому, що ви можете мати один і той же перегляд використання різних головних сторінок залежно від поточного стану виконання.
StriplingWarrior

1
Мені дуже подобається ця відповідь - інші окреслені підходи здаються дещо складними.
Падді

2
На мою думку, це найелегантніше рішення.
автомат

1
Таке рішення здається і мені найкращим. Завдяки мільйонів!
JimDaniel

1
Це чудовий спосіб, але пам’ятайте, що вам все одно потрібно вказати маршрути до ваших «часткових дій». Дивіться цю відповідь stackoverflow.com/a/3553617/56621
Олексій

20

EDIT

Загальна помилка дала кращу відповідь нижче. Прочитайте, будь ласка!

Оригінальний відповідь

Microsoft фактично розмістила запис про "офіційний" спосіб вирішення цього питання. Це забезпечує поетапне ознайомлення з поясненням їх міркувань.

Коротше кажучи, вони рекомендують використовувати абстрактний клас контролера, але подивіться самі.


СПАСИБІ! Цей приклад - ТОЧНО, що я роблю ... категорія на кожній сторінці, що надходить із бази даних.
Мартін

Скотт Ґетері, один з авторів MVC, рекомендує рішення, яке надає @Generic Error нижче
Саймон Фокс

1
+1 для спрямування на найкращу відповідь, навіть коли ваша офіційно права і прийнята як відповідь ОП.
ІсмаїлС

+1 для спрямування на найкращу відповідь, навіть коли ваша офіційно права і прийнята як відповідь ОП.
Дейв Джеллісон

Насправді, найкраща відповідь на даний момент у Тодда Меньєра.
andreialecu

7

Абстрактні контролери - хороша ідея, і я не знайшов кращого способу. Мені цікаво також побачити, що зробили інші люди.



2

Я вважаю, що загальний батьківський зв'язок для всіх модельних об'єктів, які ви передаєте представленням, є надзвичайно корисним.

Завжди завжди є деякі загальні властивості моделі між сторінками.


0

Об'єкт Request.Params змінюється. Додавати до нього скалярні значення досить просто, як частину циклу обробки запитів. З точки зору цієї точки зору, ця інформація могла бути надана у запиті POSTSTER або FORM POST. hth


0

Я маю на увазі, що ще одним хорошим способом може бути створення інтерфейсу для перегляду з якоюсь властивістю, наприклад ParentView деякого інтерфейсу, тому ви можете використовувати його як для елементів керування, які потребують посилання на сторінку (батьківський контроль), так і для головних представлень, до яких слід отримати доступ поглядів.


0

Іншим рішенням не вистачає елегантності і потрібно занадто довго. Прошу вибачення за те, що роблю цю дуже сумну і збіднілу річ майже цілий рік пізніше:

<script runat="server" type="text/C#">
    protected override void OnLoad(EventArgs e)
    {
        base.OnLoad(e);
        MasterModel = SiteMasterViewData.Get(this.Context);
    }

    protected SiteMasterViewData MasterModel;
</script>

Так чітко я маю цей статичний метод Get () на SiteMasterViewData, який повертає SiteMasterViewData.


для багатьох це може здатися трохи хакітним або «нечистим», але це швидко виконує роботу
argh

Тьфу. Ваш код здається набагато складнішим у підтримці, якщо ви використовували Html.RenderAction ().
Дан Еспарза
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.