Передати дані у макет, спільний для всіх сторінок


124

У мене є веб-сайт, на якому є макет сторінки. Однак на цій сторінці макета є дані, які всі моделі сторінок повинні містити таку назву сторінки, назву сторінки та місце, де ми насправді є для помічника HTML, який я зробив, який здійснив певну дію. Також на кожній сторінці є свої властивості моделей перегляду.

Як я можу це зробити? Здається, що це погана ідея ввести макет, але як я можу передавати тези інформації?


10
Для всіх, хто читає відповіді тут, будь ласка, дивіться stackoverflow.com/a/21130867/706346, де ви побачите набагато простіше та акуратніше рішення, що тут розміщено будь-що.
Аврохом Ісроель

5
@AvrohomYisroel гарна пропозиція. Однак я віддаю перевагу підходу @Colin Bacon, оскільки він сильно набраний і не є ViewBag. Можливо, питання переваг. Хоча ви побачили коментар
JP Hellemons,

для mvc 5 дивіться цю відповідь: stackoverflow.com/a/46783375/5519026
Laz Ziya

Відповіді:


143

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

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

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

Редагувати: оновити з коментарів нижче

Ось простий приклад для демонстрації концепції.

Створіть модель базового перегляду, від якої успадкують усі моделі перегляду.

public abstract class ViewModelBase
{
    public string Name { get; set; }
}

public class HomeViewModel : ViewModelBase
{
}

Ваша сторінка макета може сприймати це як модель.

@model ViewModelBase
<!DOCTYPE html>
<html>
    <head>
        <meta name="viewport" content="width=device-width" />
        <title>Test</title>
    </head>
    <body>
        <header>
            Hello @Model.Name
        </header>
        <div>
            @this.RenderBody()
        </div>
    </body>
</html>

Нарешті встановіть дані в методі дії.

public class HomeController
{
    public ActionResult Index()
    {
        return this.View(new HomeViewModel { Name = "Bacon" });
    }
}

12
Але дані використовуються в макеті. Як я можу передати дані в макет?
Рушино

2
Ідеально! Я побачив свою помилку. Я забув передати модель на вигляд .. яка кульгава помилка. Дякую!
Рушино

7
Проблема такого підходу полягає в тому, що іноді не в кожному перегляді є ViewModel, тому в цьому випадку це не спрацює: O /
Cacho Santa

16
Але хіба це не вимагає, щоб кожен контролер і кожна дія містили код {Name = "Bacon"}? І якщо я хотів би додати ще одну властивість до ViewModelBase, мені доведеться перейти до кожного контролера та кожної дії та додати код, щоб заповнити цю властивість? Ви згадали "Якщо є необхідна логіка [...], це слід поставити в базовий контролер [...]". Як би це працювало, щоб усунути цей повторний код у кожному контролері та кожній дії?
Лі

5
@Lee Якщо це загальні дані на всіх сторінках, тут ви б помістили базовий контролер. Потім ваші контролери успадковують цей базовий контролер. напр public class HomeController : BaseController. Таким чином, загальний код потрібно написати лише один раз і його можна застосувати до всіх контролерів.
Колін Бекон

73

Я використовував HTML-помічник RenderAction для бритви в макеті.

@{
   Html.RenderAction("Action", "Controller");
 }

Мені це було потрібно для простої струни. Тож моя дія повертає рядок і записує її легко в поле зору. Але якщо вам потрібні складні дані, ви можете повернути PartialViewResult і модель.

 public PartialViewResult Action()
    {
        var model = someList;
        return PartialView("~/Views/Shared/_maPartialView.cshtml", model);
    }

Вам просто потрібно поставити свою модель на початок часткового перегляду "_maPartialView.cshtml", який ви створили

@model List<WhatEverYourObjeIs>

Тоді ви можете використовувати дані в моделі в цьому частковому представленні з html.


18
Це далеко не найкраща відповідь!
пряник

@gingerbreadboy погодився, що це сприяє гарній інкапсуляції та роз'єднанню проблем.
A-Dubb

35

Інший варіант - створити окремий клас LayoutModel з усіма властивостями, які вам знадобляться у макеті, а потім вставити екземпляр цього класу у ViewBag. Я використовую метод Controller.OnActionExecuting, щоб заповнити його. Потім, на початку макету, ви можете відтягнути цей об’єкт із ViewBag та продовжити доступ до цього сильно набраного об’єкта.


1
Це насправді звучить як найменш болісне рішення, чи є якісь недоліки? +1
formatc

2
Безумовно, найкраще рішення, і я не бачу жодних недоліків.
Wiktor Zychla

7
Я не бачу, що це дає тобі. Якщо у вас є клас зі всіма властивостями, необхідними для макета, навіщо турбуватися додавати його в ViewBag, щоб знову повернути його назад? Використовуйте модель у вікні компонування, ви все ще можете заповнити модель у OnActionExecuting. Використання ViewBag також означає, що ви втрачаєте безпеку типу свого контролера, ніколи не є хорошою справою.
Колін Бекон

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

5
@ColinBacon Ще однією перевагою цього варіанту є те, що для Ваших дій не потрібно завжди мати переглянуті моделі. Крім того, я б заперечив, що розробники, які повинні знати, що вони повинні завжди успадковувати свої моделі перегляду від бази, є недоліком.
Джош Ное

28

Імовірно, основним випадком використання для цього є отримання базової моделі для перегляду для всіх (або більшості) дій контролера.

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

Правильно, що це все-таки логіка контролера, тому що ми заповнюємо модель перегляду для повернення до перегляду. Таким чином, правильне місце для цього - у контролері.

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

Ми все ще хочемо додаткової переваги сильно набраного ViewModel

Таким чином, я створив BaseViewModel і BaseController. Усі контролери ViewModels успадкують від BaseViewModel та BaseController відповідно.

Код:

BaseController

public class BaseController : Controller
{
    protected override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        base.OnActionExecuted(filterContext);

        var model = filterContext.Controller.ViewData.Model as BaseViewModel;

        model.AwesomeModelProperty = "Awesome Property Value";
        model.FooterModel = this.getFooterModel();
    }

    protected FooterModel getFooterModel()
    {
        FooterModel model = new FooterModel();
        model.FooterModelProperty = "OMG Becky!!! Another Awesome Property!";
    }
}

Зверніть увагу на використання OnActionExecuted , прийнятого з цієї публікації SO

HomeController

public class HomeController : BaseController
{
    public ActionResult Index(string id)
    {
        HomeIndexModel model = new HomeIndexModel();

        // populate HomeIndexModel ...

        return View(model);
    }
}

BaseViewModel

public class BaseViewModel
{
    public string AwesomeModelProperty { get; set; }
    public FooterModel FooterModel { get; set; }
}

HomeViewModel

public class HomeIndexModel : BaseViewModel
{

    public string FirstName { get; set; }

    // other awesome properties
}

FooterModel

public class FooterModel
{
    public string FooterModelProperty { get; set; }
}

Layout.cshtml

@model WebSite.Models.BaseViewModel
<!DOCTYPE html>
<html>
<head>
    < ... meta tags and styles and whatnot ... >
</head>
<body>
    <header>
        @{ Html.RenderPartial("_Nav", Model.FooterModel.FooterModelProperty);}
    </header>

    <main>
        <div class="container">
            @RenderBody()
        </div>

        @{ Html.RenderPartial("_AnotherPartial", Model); }
        @{ Html.RenderPartial("_Contact"); }
    </main>

    <footer>
        @{ Html.RenderPartial("_Footer", Model.FooterModel); }
    </footer>

    < ... render scripts ... >

    @RenderSection("scripts", required: false)
</body>
</html>

_Nav.cshtml

@model string
<nav>
    <ul>
        <li>
            <a href="@Model" target="_blank">Mind Blown!</a>
        </li>
    </ul>
</nav>

Сподіваємось, це допомагає.


2
Я використовував такий підхід, але віддаю перевагу успадковуванню з інтерфейсу, а не базового класу. Так я зробив: var model = filterContext.Controller.ViewData.Model як IBaseViewModel, якщо (модель! = Null) {model.AwesomeModelProperty = "Awesome Value Value"; }
Том Геркен

2
чудова відповідь, я віддав перевагу цьому перед усіма іншими.
Jynn

1
Чудова відповідь, але у мене є питання. "Що робити, якщо у мене є кілька переглядів, у яких немає ViewModels ...?"
Ісма Харо

Спробував це, але в індексній дії, OnActionExecuted заповнює FooterModel, а потім створюється новий HomeIndexModel з нульовим FooterModel :(
SteveCav

1
@drizzie: у базовому контролері модель є локальною змінною у методі Filter: var model = filterContext.Controller.ViewData.Model як BaseViewModel. Я не розумію, як MVC розуміє, що ця локальна змінна збігається з моделлю, яку HomeController надсилає для перегляду.
Hooman Bahreini

9

Вам не доведеться возитися з діями або змінювати модель, просто використовуйте базовий контролер і відкиньте наявний контролер з контексту перегляду макета.

Створіть базовий контролер з потрібними загальними даними (назва / сторінка / місцезнаходження тощо) та ініціалізація дій ...

public abstract class _BaseController:Controller {
    public Int32 MyCommonValue { get; private set; }

    protected override void OnActionExecuting(ActionExecutingContext filterContext) {

        MyCommonValue = 12345;

        base.OnActionExecuting(filterContext);
    }
}

Переконайтесь, що кожен контролер використовує базовий контролер ...

public class UserController:_BaseController {...

Відкиньте наявний базовий контролер з контексту перегляду на вашу _Layout.cshmlсторінку ...

@{
    var myController = (_BaseController)ViewContext.Controller;
}

Тепер ви можете посилатися на значення в базовому контролері зі сторінки макета.

@myController.MyCommonValue

ОНОВЛЕННЯ

Ви також можете створити розширення сторінки, яке дозволить вам використовувати this.

//Allows typed "this.Controller()." in cshtml files
public static class MyPageExtensions {
    public static _BaseController Controller(this WebViewPage page) => Controller<_BaseController>(page);
    public static T Controller<T>(this WebViewPage page) where T : _BaseController => (T)page.ViewContext.Controller;
}

Тоді вам залишається лише пам’ятати, щоб використовувати, this.Controller()коли ви хочете контролер.

@{
    var myController = this.Controller(); //_BaseController
}

або конкретний контролер, який успадковує від _BaseController...

@{
    var myController = this.Controller<MyControllerType>();
}

Який еквівалент цього в ядрі .net? Оскільки ViewContext.Controller немає, і в ланцюжку спадкування є деякі зміни
Jayanth Thyagarajan

4

якщо ви хочете пройти всю модель, вийдіть так у макеті:

@model ViewAsModelBase
<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta charset="utf-8"/>
    <link href="/img/phytech_icon.ico" rel="shortcut icon" type="image/x-icon" />
    <title>@ViewBag.Title</title>
    @RenderSection("styles", required: false)    
    <script type="text/javascript" src="http://code.jquery.com/jquery-1.8.3.min.js"></script>
    @RenderSection("scripts", required: false)
    @RenderSection("head", required: false)
</head>
<body>
    @Html.Action("_Header","Controller", new {model = Model})
    <section id="content">
        @RenderBody()
    </section>      
    @RenderSection("footer", required: false)
</body>
</html>

і додайте це в контролер:

public ActionResult _Header(ViewAsModelBase model)

4

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

У вас повинен бути базовий контролер на всіх контролерах. Додайте дані про макет OnActionExecuting у свій базовий контролер (або OnActionExecuted, якщо ви хочете відкласти це) ...

public class BaseController : Controller
{
    protected override void OnActionExecuting(ActionExecutingContext     
        filterContext)
    {
        ViewBag.LayoutViewModel = MyLayoutViewModel;
    }
}

public class HomeController : BaseController
{
    public ActionResult Index()
    {
        return View(homeModel);
    }
}

Потім у своєму _Layout.cshtml витягніть ViewModel з ViewBag ...

@{
  LayoutViewModel model = (LayoutViewModel)ViewBag.LayoutViewModel;
}

<h1>@model.Title</h1>

Або ...

<h1>@ViewBag.LayoutViewModel.Title</h1>

Це не перешкоджає кодуванню контролерів вашої сторінки або перегляду моделей.


Мені подобається ваша ідея, але як бути, якщо у вас є MyLayoutViewModelдинамічно створений, як я можу передавати деякі параметри OnActionExecutingметоду?
Rajmond Burgaj

1
Ух, вам все одно потрібно base.OnActionExecuting(filterContext)у вашому OnActionExecutingметоді !!!
ErikE

4

Створення базового виду, який представляє модель вигляду «Макет», - це жахливий підхід. Уявіть, що ви хочете мати модель, яка представляє навігацію, визначену в макеті. Ви б зробилиCustomersViewModel : LayoutNavigationViewModel ? Чому? Чому слід передавати дані навігаційної моделі через кожну модель перегляду, яку ви маєте в рішенні?

Модель перегляду макета повинна бути присвячена самостійно і не повинна змушувати інші моделі перегляду залежати від неї.

Натомість ви можете зробити це у своєму _Layout.cshtmlфайлі:

@{ var model = DependencyResolver.Current.GetService<MyNamespace.LayoutViewModel>(); }

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

напр

public class LayoutViewModel
{
    private readonly DataContext dataContext;
    private readonly ApplicationUserManager userManager;

    public LayoutViewModel(DataContext dataContext, ApplicationUserManager userManager)
    {
    }
}

Де ви заповнюєте цю модель? У BaseController також?
ndberg

Я думаю, це було б гарною ідеєю для Scopedоб’єкта моделі компонування в ASP..Net Core.
Джеймс Вілкінс

Я б не мав уявлення про те, щоб отримати залежність. Це точно не "MVC". Локатор послуг - це анти-шаблон .
Jiveman

Всупереч поширеній думці, сервіс-локатор не є антидіаграмою, і насправді це не має нічого спільного з MVC, ви просто накидаєте гучні слова @Jiveman? blog.gauffin.org/2012/09/service-locator-is-not-an-anti-pattern
hyankov

Основним моментом Джауффіна в цій статті є те, що термін "антидіапазон" не слід застосовувати до "Локатора послуг", оскільки може бути принаймні деякі дійсні способи використання SL. Справедливий момент. Однак, як видно в деяких його власних коментарях до обговорення, він припускає, що, хоча SL може бути правильним підходом при створенні бібліотек та рамок, він не обов'язково рекомендується створювати додатки (що я вважав би питанням ОП і ця дискусія тут обертається навколо).
Jiveman

3

Інші відповіді висвітлювали майже все про те, як ми можемо передати модель на нашу сторінку розмітки. Але я знайшов спосіб, за допомогою якого ви можете динамічно передати змінні на вашу сторінку макета, не використовуючи жодної моделі чи часткового перегляду у своєму макеті. Скажімо, у вас є ця модель -

public class SubLocationsViewModel
{
    public string city { get; set; }
    public string state { get; set; }
}

І ви хочете динамічно отримувати місто та державу. Наприклад, наприклад

у вашому index.cshtml ви можете помістити ці дві змінні у ViewBag

@model  MyProject.Models.ViewModel.SubLocationsViewModel
@{
    ViewBag.City = Model.city;
    ViewBag.State = Model.state;
}

А потім у своєму layout.cshtml ви можете отримати доступ до цих змінних

<div class="text-wrap">
    <div class="heading">@ViewBag.City @ViewBag.State</div>
</div>

це чудово працює, @stun_Gravy чи є падіння за допомогою ViewBag для передачі даних, таких як роль чи рівень доступу користувачів?
3not3

3

Є ще один спосіб вирішити це. Можливо, це не найчистіший спосіб з архітектурної точки зору, але це дозволяє уникнути великого болю, пов'язаного з іншими відповідями. Просто введіть службу в макет Razor, а потім зателефонуйте методу, який отримує необхідні дані:

@inject IService myService

Потім пізніше у вигляді макета:

@if (await myService.GetBoolValue()) {
   // Good to go...
}

Знову ж таки, не в чистоті з точки зору архітектури (очевидно, що сервіс не слід вводити безпосередньо у вигляд), але це робить роботу.


Чи не найчистіший спосіб? Я не погоджуюсь. Я думаю, що це так само чисто, як виходить: об’єкт передається з місця, де він створений прямо до того місця, де ви хочете, щоб він був, не "забруднюючи" інших контролерів предметами, які їм не потрібно бачити. Використання @inject- це найкраще рішення, на мою думку.
dasblinkenlight

1
Думаючи про це більше, можливо, ти маєш рацію. Той факт, що цей метод дозволяє уникнути сильного болю, є ознакою того, що, можливо, це найчистіший спосіб. Я працюю над дуже великим додатком ASP.NET Core, і я використовую цю схему для таких речей, як логіка навігаційної сукупності, дані заголовків, які є на більшості сторінок, подібні речі. Я уникав такого сильного болю, роблячи це замість цього.
Андрій

2

Ви також можете скористатися програмою RenderSection , вона допомагає вводити ваші Modelдані у _Layoutподання.

Ви можете вводити View Modelдані, Json, Script, CSS, і HTMLт.д.

У цьому прикладі я впорскую Jsonз мого Indexперегляду в представлення Layout.

Index.chtml

@section commonLayoutData{

    <script>

        var products = @Html.Raw(Json.Encode(Model.ToList()));

    </script>

    }

_Layout.cshtml

@RenderSection("commonLayoutData", false)

Це виключає необхідність створення окремої Бази View Model .

Надія комусь допомагає.


1
Ідеальне рішення , коли ви тільки потрібно зробити що - то конкретне для кількох вистав.
Кунал

1

те, що я зробив, дуже просто, і це працює

Заявіть про статичну властивість у будь-якому контролері або ви можете зробити клас даних зі статичними значеннями, якщо ви хочете так:

public static username = "Admin";
public static UserType = "Administrator";

Ці значення можуть бути оновлені контролерами на основі операцій. пізніше ви можете використовувати їх у своїй _Layout

В _layout.cshtml

@project_name.Controllers.HomeController.username
@project_name.Controllers.HomeController.UserType

1
Завжди корисно додати відповідь до своєї відповіді, щоб зробити її більш зрозумілою та зрозумілою. Прочитайте, будь ласка, stackoverflow.com/help/how-to-answer .
32cupo

0

Чому ніхто не запропонував методи розширення на ViewData?

Варіант №1

Мені здається, найменш нав'язливим і найпростішим рішенням проблеми. Немає твердо кодованих рядків. Жодних накладених обмежень немає. Немає магічного кодування. Немає складного коду.

public static class ViewDataExtensions
{
    private const string TitleData = "Title";
    public static void SetTitle<T>(this ViewDataDictionary<T> viewData, string value) => viewData[TitleData] = value;
    public static string GetTitle<T>(this ViewDataDictionary<T> viewData) => (string)viewData[TitleData] ?? "";
}

Встановлення даних на сторінці

ViewData.SetTitle("abc");

Варіант №2

Ще один варіант - полегшити декларацію поля.

public static class ViewDataExtensions
{
    public static ViewDataField<string, V> Title<V>(this ViewDataDictionary<V> viewData) => new ViewDataField<string, V>(viewData, "Title", "");
}

public class ViewDataField<T,V>
{
    private readonly ViewDataDictionary<V> _viewData;
    private readonly string _field;
    private readonly T _defaultValue;

    public ViewDataField(ViewDataDictionary<V> viewData, string field, T defaultValue)
    {
        _viewData = viewData;
        _field = field;
        _defaultValue = defaultValue;
    }

    public T Value {
        get => (T)(_viewData[_field] ?? _defaultValue);
        set => _viewData[_field] = value;
    }
}

Встановлення даних на сторінці. Декларування простіше, ніж перший варіант, але синтаксис використання трохи довший.

ViewData.Title().Value = "abc";

Варіант №3

Потім можна поєднати це з поверненням одного об'єкта, що містить усі поля, пов’язані з компонуванням, зі своїми значеннями за замовчуванням.

public static class ViewDataExtensions
{
    private const string LayoutField = "Layout";
    public static LayoutData Layout<T>(this ViewDataDictionary<T> viewData) => 
        (LayoutData)(viewData[LayoutField] ?? (viewData[LayoutField] = new LayoutData()));
}

public class LayoutData
{
    public string Title { get; set; } = "";
}

Встановлення даних на сторінці

var layout = ViewData.Layout();
layout.Title = "abc";

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

  • Найпростіша заява полів і значень за замовчуванням.

  • Найпростіший синтаксис використання при встановленні декількох полів.

  • Дозволяє встановлювати різні види даних у ViewData (наприклад, макет, заголовок, навігація).

  • Дозволяє додатковий код і логіку в класі LayoutData.

PS Не забудьте додати простір імен ViewDataExtensions у _ViewImports.cshtml


0

Ви можете створити файл бритви в папці App_Code, а потім отримати доступ до нього зі своїх сторінок перегляду.

Проект> Репозиторій / IdentityRepository.cs

namespace Infrastructure.Repository
{
    public class IdentityRepository : IIdentityRepository
    {
        private readonly ISystemSettings _systemSettings;
        private readonly ISessionDataManager _sessionDataManager;

        public IdentityRepository(
            ISystemSettings systemSettings
            )
        {
            _systemSettings = systemSettings;
        }

        public string GetCurrentUserName()
        {
            return HttpContext.Current.User.Identity.Name;
        }
    }
}

Проект> App_Code / IdentityRepositoryViewFunctions.cshtml:

@using System.Web.Mvc
@using Infrastructure.Repository
@functions
{
    public static IIdentityRepository IdentityRepositoryInstance
    {
        get { return DependencyResolver.Current.GetService<IIdentityRepository>(); }
    }

    public static string GetCurrentUserName
    {
        get
        {
            var identityRepo = IdentityRepositoryInstance;
            if (identityRepo != null)
            {
                return identityRepo.GetCurrentUserName();
            }
            return null;
        }
    }
}

Проект> Перегляди / Спільний / _Layout.cshtml (або будь-який інший .cshtml файл)

<div>
    @IdentityRepositoryViewFunctions.GetCurrentUserName
</div>

-1

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

створіть новий частковий вигляд у Спільному каталозі та зателефонуйте на часткове подання у своєму макеті як

@Html.Partial("MyPartialView")

у вашому частковому перегляді ви можете зателефонувати на ваш db і виконати все, що хочете зробити

@{
    IEnumerable<HOXAT.Models.CourseCategory> categories = new HOXAT.Models.HOXATEntities().CourseCategories;
}

<div>
//do what ever here
</div>

якщо ви додали базу даних Entity Framework


1
Як ніколи не слід нести відповідальність Погляду для отримання власної Моделі.
Оксонамхаммер

-1

Неймовірно, що тут ніхто цього не сказав. Передача моделі перегляду через базовий контролер - це безлад. Ми використовуємо претензії користувачів для передачі інформації на сторінку макета (наприклад, для відображення даних про користувача на навігаційній панелі). Є ще одна перевага. Дані зберігаються за допомогою файлів cookie, тому не потрібно отримувати дані в кожному запиті за допомогою партій. Просто зробіть кілька "гуглих чистих претензій на особистість".


@CodeSmith що? Я пропоную рішення.
makore

Моє погано, думав, що це питання, але дивіться, що відповідь зараз, видалено.
CodeSmith

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

-6

Ви можете використовувати так:

 @{ 
    ApplicationDbContext db = new ApplicationDbContext();
    IEnumerable<YourModel> bd_recent = db.YourModel.Where(m => m.Pin == true).OrderByDescending(m=>m.ID).Select(m => m);
}
<div class="col-md-12">
    <div class="panel panel-default">
        <div class="panel-body">
            <div class="baner1">
                <h3 class="bb-hred">Recent Posts</h3>
                @foreach(var item in bd_recent)
                {
                    <a href="/BaiDangs/BaiDangChiTiet/@item.ID">@item.Name</a>
                }
            </div>
        </div>
    </div>
</div>

7
Підключення до бази даних - це дуже погана ідея.
1_буг
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.