ASP.NET MVC Core自定义TagHelper

Models文件夹


   public class City
	{
		public string Name { get; set; }
		public string Country { get; set; }
		public int? Population { get; set; }
	}
public interface IRepository
	{
		IEnumerable<City> Cities { get; }

		void AddCity(City newCity);
	}
using System.Collections.Generic;

namespace MyTagHelper.Models
{
	public class MemoryRepository : IRepository
	{
		private readonly List<City> _cities = new List<City>
		{
			new City {Name = "伦敦", Country = "英国", Population = 8539000},
			new City {Name = "纽约", Country = "美国", Population = 8406000},
			new City {Name = "圣荷西", Country ="美国", Population = 998537},
			new City {Name = "巴黎", Country = "法国", Population = 2244000}
		};

		public IEnumerable<City> Cities => _cities;

		public void AddCity(City newCity)
		{
			_cities.Add(newCity);
		}
	}
}

TagHelpers文件夹

ButtonTagHelper.cs

using Microsoft.AspNetCore.Razor.TagHelpers;

namespace MyTagHelper.TagHelpers
{
	[HtmlTargetElement("button", Attributes = "bs-button-color", ParentTag = "form")]
	[HtmlTargetElement("a", Attributes = "bs-button-color", ParentTag = "form")]
	public class ButtonTagHelper : TagHelper
	{
		public string BsButtonColor { get; set; }

		public override void Process(TagHelperContext context, TagHelperOutput output)
		{
			output.Attributes.SetAttribute("class", $"btn btn-{BsButtonColor}");
		}
	}
}

ContentWrapperTagHelper.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.AspNetCore.Razor.TagHelpers;

namespace MyTagHelper.TagHelpers
{
	[HtmlTargetElement("div", Attributes = "title")]
    public class ContentWrapperTagHelper : TagHelper
    {
		public bool IncludeHeader { get; set; } = true;
		public bool IncludeFooter { get; set; } = true;

		public string Title { get; set; }

	    public override void Process(TagHelperContext context, TagHelperOutput output)
	    {
		    output.Attributes.SetAttribute("class", "panel-body");

			var title = new TagBuilder("h2");
		    title.InnerHtml.Append(Title);

			var container = new TagBuilder("div");
		    container.Attributes["class"] = "bg-info panel-body";
		    container.InnerHtml.AppendHtml(title);


			if (IncludeHeader)
		    {
			    output.PreElement.SetHtmlContent(container);
		    }

		    if (IncludeFooter)
		    {
				output.PostElement.SetHtmlContent(container);
			}
	    }
    }
}

CoordinatingTagHelpers.cs

using Microsoft.AspNetCore.Razor.TagHelpers;

namespace MyTagHelper.TagHelpers
{
	[HtmlTargetElement("div", Attributes = "theme")]
	public class ButtonGroupThemeTagHelper : TagHelper
	{
		public string Theme { get; set; }

		public override void Process(TagHelperContext context,
			TagHelperOutput output)
		{
			context.Items["theme"] = Theme;
		}
	}

	[HtmlTargetElement("button", ParentTag = "div")]
	[HtmlTargetElement("a", ParentTag = "div")]
	public class ButtonThemeTagHelper : TagHelper
	{
		public override void Process(TagHelperContext context,
			TagHelperOutput output)
		{
			if (context.Items.ContainsKey("theme"))
				output.Attributes.SetAttribute("class",
					$"btn btn-{context.Items["theme"]}");
		}
	}
}

FormButtonTagHelper.cs

using System;
using Microsoft.AspNetCore.Razor.TagHelpers;

namespace MyTagHelper.TagHelpers
{
	[HtmlTargetElement("formbutton")]
	public class FormButtonTagHelper : TagHelper
	{
		public string Type { get; set; } = "Submit";

		public string BgColor { get; set; } = "primary";

		public override void Process(TagHelperContext context, TagHelperOutput output)
		{
			output.TagName = "button";
			output.TagMode = TagMode.StartTagAndEndTag;
			output.Attributes.SetAttribute("class", $"btn btn-{BgColor}");
			output.Attributes.SetAttribute("type", Type);
			output.Content.SetContent(Type == "submit" ? "Add" : "Reset");
		}
	}
}

LabelAndInputTagHelper.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc.ViewFeatures;
using Microsoft.AspNetCore.Razor.TagHelpers;

namespace MyTagHelper.TagHelpers
{
	[HtmlTargetElement("label", Attributes = "helper-for")]
	[HtmlTargetElement("input", Attributes = "helper-for")]
	public class LabelAndInputTagHelper : TagHelper
    {
	    public ModelExpression HelperFor { get; set; }

	    public override void Process(TagHelperContext context, TagHelperOutput output)
	    {
		    if (output.TagName == "label")
		    {
			    output.TagMode = TagMode.StartTagAndEndTag;
				output.Content.Append(HelperFor.Name);
				output.Attributes.SetAttribute("for", HelperFor.Name);
			} else if (output.TagName == "input")
		    {
			    output.TagMode = TagMode.SelfClosing;
				output.Attributes.SetAttribute("name", HelperFor.Name);
				output.Attributes.SetAttribute("class", "form-control");
				if (HelperFor.Metadata.ModelType == typeof(int?))
				{
					output.Attributes.SetAttribute("type", "number");
				}
			}
	    }
    }
}

SelectiveTagHelper.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.AspNetCore.Mvc.ViewFeatures;
using Microsoft.AspNetCore.Razor.TagHelpers;

namespace MyTagHelper.TagHelpers
{
	[HtmlTargetElement(Attributes = "show-for-action")]
	public class SelectiveTagHelper : TagHelper
	{
		public string ShowForAction { get; set; }
		[ViewContext]
		[HtmlAttributeNotBound]
		public ViewContext ViewContext { get; set; }
		public override void Process(TagHelperContext context,
		TagHelperOutput output)
		{
			if (!ViewContext.RouteData.Values["action"].ToString()
			.Equals(ShowForAction, StringComparison.OrdinalIgnoreCase))
			{
				output.SuppressOutput();
			}
		}
	}
}

TableCellTagHelper.cs

using Microsoft.AspNetCore.Razor.TagHelpers;

namespace MyTagHelper.TagHelpers
{
	[HtmlTargetElement("td", Attributes = "wrap")]
	public class TableCellTagHelper : TagHelper
	{
		public override void Process(TagHelperContext context, TagHelperOutput output)
		{
			output.PreContent.SetHtmlContent("<b><i>");
			output.PostContent.SetHtmlContent("</i></b>");
		}
	}
}

HomeController.cs

using Microsoft.AspNetCore.Mvc;
using CustomTagHelper.Models;

namespace MyTagHelper.Controllers
{
	public class HomeController : Controller
	{
		private readonly IRepository _repository;

		public HomeController(IRepository repo)
		{
			_repository = repo;
		}

		public ViewResult Index() => View(_repository.Cities);

		public ViewResult Create() => View();

		[HttpPost]
		public IActionResult Create(City city)
		{
			_repository.AddCity(city);
			return RedirectToAction("Index");
		}
	}
}

视图

Index.cshtml

@model IEnumerable<City>
@{ Layout = "_Layout"; }
<table class="table table-condensed table-bordered">
    <thead class="bg-primary">
        <tr>
            <th>名称</th>
            <th>国家</th>
            <th class="text-right">人口</th>
        </tr>
    </thead>
    <tbody>
        @foreach (var city in Model)
        {
            <tr>
                <td wrap>@city.Name</td>
                <td>@city.Country</td>
                <td class="text-right">@city.Population?.ToString("#,###")</td>
            </tr>
        }
    </tbody>
</table>
<a href="/Home/Create" class="btn btn-primary">创建</a>

Create.cshtml

@model City
@{ Layout = "_Layout"; }
<form method="post" action="/Home/Create">
    <div class="form-group">
        <label helper-for="Name" />
        <input helper-for="Name" />
    </div>
    <div class="form-group">
        <label helper-for="Country" />
        <input helper-for="Country" />
    </div>
    <div class="form-group">
        <label helper-for="Population" />
        <input helper-for="Population" />
    </div>
    @*<formbutton type="submit" bg-color="danger" />
    <formbutton type="reset" />
    <a bs-button-color="primary" href="/Home/Index">Cancel</a>*@
    <div theme="danger">
        <button type="submit">添加</button>
        <button type="reset">重置</button>
        <a href="/Home/Index">取消</a>
    </div>
</form>

_Layout.cshtml

<!DOCTYPE html>
<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>城市</title>
    <link href="/lib/bootstrap/dist/css/bootstrap.css" rel="stylesheet" />
</head>
<body class="panel-body">
    <div show-for-action="Index" class="panel-body bg-danger">
        <h2>重要的信息</h2>
    </div>
<div title="城市列表">@RenderBody()</div>
</body>
</html>

运行结果如图:

这里写图片描述


这里写图片描述


这里写图片描述

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值