ASP.NET Core 部分ビューでビューモデルの定義に従い、生成する要素のテキストや属性を編集する

2020/10/12 (更新:2020/11/19)

ASP.NETCore

環境や条件等に応じ画面項目をカスタマイズする画面のコントロール制御を想定しています。
ビューモデルに画面項目の編集内容を定義します。
画面項目を部分ビュータグヘルパーで実装し、ビューモデルの項目定義に従い、部分ビューで生成する要素のテキストや属性を編集します。
サンプルのリポジトリです。
github.com/tassk-work/AspNetCore/tree/master/PartialView03

コントローラー

public class HomeController : Controller
{
    public IActionResult Index()
    {
        var model = new HomeViewModel
        {
            Item01 = "01",
            ItemMeta = new List
            {
                new ItemMeta
                {
                    ItemId = nameof(HomeViewModel.Item01),
                    Element01 = "customized text",
                    Attribute01 = "customized attribute",
                },
            }
        };
        return View(model);
    }
}
ビューモデル

public class BaseModel
{
    public List ItemMeta { get; set; }
}

public class ItemMeta
{
    public string ItemId { get; set; }
    public string Attribute01 { get; set; }
    public string Element01 { get; set; }
}

public class HomeViewModel : BaseModel
{
    public string Item01 { get; set; }
}
部分ビュータグヘルパー

[HtmlTargetElement(TAG_NAME)]
public class SampleTagHelper : PartialTagHelper
{
    public const string TAG_NAME = "sample";
    private const string ItemIdAttributeName = "itemid";

    [HtmlAttributeName(ItemIdAttributeName)]
    public string ItemId { get; set; }

    public string InnerHtml { get; private set; }
    public string ChildHtml
    {
        get
        {
            var html = InnerHtml;
            var itemMeta = _baseModel.ItemMeta.FirstOrDefault(x => x.ItemId == ItemId);
            html = Regex.Replace(html, $@"(?<=class="".*element01.*"".*?>)(.*)(?=<)", itemMeta.Element01);
            html = Regex.Replace(html, $@"(?<=attribute01="")(.*?)(?="")", itemMeta.Attribute01);
            return html;
        }
    }
    private BaseModel _baseModel;

    public SampleTagHelper(
        ICompositeViewEngine viewEngine,
        IViewBufferScope viewBufferScope) : base(viewEngine, viewBufferScope)
    {
        Model = this;
        Name = "_Sample";
    }

    public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
    {
        InnerHtml = (await output.GetChildContentAsync()).GetContent();
        _baseModel = ViewContext.ViewData.Model as BaseModel;

        await base.ProcessAsync(context, output);
    }
}
部分ビュー

@model PartialView03.TagHelpers.SampleTagHelper
<div class="form-group">
    @Html.Raw(Model.ChildHtml)
</div>
ビュー

@model PartialView03.Models.HomeViewModel
<div>
    <sample itemid="@nameof(Model.Item01)">
        <div>
            <label class="element01">xxx</label>
            <input asp-for="Item01" attribute01="xxx">
        </div>
    </sample>
</div>

コメント

コメントはありません。