#c_sharp #aspnet #aspnet_mvc #mvc
Доброго дня, друзья! Тщательно готовился перед тем как задать вопрос. И вот. Задача такая - есть часто повторяемый код вёрстки (сам код специально упрощён, на деле там много всего из-за чего и встал, собственно, вопрос более грамотной реализации). Хочется сделать подобный Partial View:@RenderBodyУ нас есть IDENT (идентификатор) и какое-то тело. Чтобы далее в какой-либо другой View вызывать нечто подобное: @using(Html.DrawMyCustomSection("ident12345")) { Передать в тело } Чтобы на выходе иметь:Передать в телоВопрос в самой "элегантности" решения. Самый простой способ - отказаться от Partial View вообще и рендерить всё средствами MvcHtmlString. Но это, сдаётся мне, моветон и я его не рассматриваю, как достойный вариант. Второй способ - использовать кастомный хелпер с реализацией IDisposable и рендерингом PartialView с заменой контрольных строк {IDENT} и {BODY} на своё. Этот вариант вроде как лучше, но ненамного :) Третий способ - строготипизированная модель для PartialView, в которой всё передавать. Хороший способ, как по мне. Но не могу понять как правильно передать само тело в PartialView и как там его разворачивать. Также можно накрутить реализации с ViewBag / ViewData, но это совсем плохо. Отсюда вопрос: Как правильно, грамотно и красиво передать в PartialView параметры и отрендерить тело в основное представление? Использовать строготипизированную модель, тогда как в неё записать (получить) то, что было в основной вьюшке указано в теле? Буду рад любому ответу и\или примеру. Спасибо!
Ответы
Ответ 1
Насколько я понял, вам требуется создать аналог @using(Html.BegibForm()). Т.о. будет возможность оборачивать в div с заданным id другую razor разметку. Для этого потребуется создать класс или добавить в существующий новый html helper (зависит от того как вы их храните). Далее пример для отдельного класса: using System; using System.IO; using System.Web.Mvc; namespace MyWebApplication.Helpers { public static class UserIdentityHelper { private const string TagName = "div"; private class UserIdentityContainer : IDisposable { private readonly TextWriter _writer; public UserIdentityContainer(TextWriter writer) { _writer = writer; } public void Dispose() { var builder = new TagBuilder(TagName); _writer.WriteLine(builder.ToString(TagRenderMode.EndTag)); } } public static IDisposable UserIdentity(this HtmlHelper htmlHelper, string userIdentifier) { var builder = new TagBuilder(TagName); builder.Attributes.Add("id", userIdentifier); var writer = htmlHelper.ViewContext.Writer; writer.WriteLine(builder.ToString(TagRenderMode.StartTag)); return new UserIdentityContainer(writer); } } } Не забудьте добавить в web.config новый namespace (если еще не добавлено):... Вызов будет выглядеть, например, так @using (Html.UserIdentity("ident12345")) {... Hello ident12345!
} И в результате будет получена разметка следующего вида:Обратите внимание, что вызов UserIdentity возвращает класс, который реализует IDisposable, а закрывающий тэг создается с параметром TagRenderMode.EndTagHello ident12345!
Ответ 2
Мне кажется именно для подобных целей и был создан View Component Создаем класс с названием нового компонента [ViewComponent] public class ShowIdent { public string Invoke(string idParam, string textParam) { return $"{textParam}"; } } Вызываем в нужной вьюхе @await Component.InvokeAsync("ShowIdent", new { idParam = "ident12345", textParam = "Передать в тело"}) Более подробно о View Component тут: https://metanit.com/sharp/aspnet5/7.6.php
Комментариев нет:
Отправить комментарий