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


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.