helper扩展现有方法而不覆盖

helper扩展现有方法而不覆盖

本文介绍了C#html-helper扩展现有方法而不覆盖?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经搜索过问题,发现可能,但我仍然需要一些帮助。

I have already searched for the question and found possible answer, but I still need some help.

我想写一个html-helper来扩展已经存在的LabelFor方法

I am trying to write an html-helper to extend functionality of already existing LabelFor method

public static MvcHtmlString LabelFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression, IDictionary<string, object> htmlAttributes)
  {
     ModelMetadata metadata = ModelMetadata.FromLambdaExpression(expression, html.ViewData);


     string htmlFieldName = ExpressionHelper.GetExpressionText(expression);
     //string labelText = metadata.DisplayName ?? metadata.PropertyName ?? htmlFieldName.Split('.').Last();
     var labelText = html.LabelFor(expression);
     if (String.IsNullOrEmpty(labelText.ToString()))
     {
        return MvcHtmlString.Empty;
     }

     if (metadata.IsRequired)
     {
        labelText = new MvcHtmlString(labelText.ToString().Substring(0, labelText.ToString().Length - 8).Trim() +
            "<span style=\"color:red\" class=\"required-marker\">*</span></label>");
     }
     TagBuilder tag = new TagBuilder("label");
     tag.MergeAttributes(htmlAttributes);
     tag.Attributes.Add("for", html.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldId(htmlFieldName));
     tag.SetInnerText(labelText.ToString());
     return MvcHtmlString.Create(tag.ToString(TagRenderMode.Normal));
  }



我试图添加一个功能,其中Method将检查变量是否有required标志,然后执行某些操作(在这种情况下在标签结尾添加红色)

I am trying to add a functionality, where Method would check if variable has a "required" flag, and then performs something (adds red * at the end of label in that case)

[Required]
[Display(Name = "Year")]
public string ProjectYr { get; set; }

但是,我觉得我要覆盖整个LabelFor功能。有没有办法简单地添加新的功能到现有的LabelFor方法,同时保留原始的所有功能,而不覆盖它? 覆写无法运作,因为我的方法是静态的。

However, I feel like I am overwriting the entire LabelFor functionality. Is there a way to simply add new functionality to existing LabelFor method while preserving all functions of the original without overriding it? Override doesn't work anyway since my method is static.

非常感谢您! p>

Thank you very much in advance!

推荐答案

这是一个完整的例子,你做的是什么

Here's a complete example that does what your asking

public static class LabelExtensions
{
    public static MvcHtmlString LabelFor<TModel, TValue>(this HtmlHelper<TModel> html,
        Expression<Func<TModel, TValue>> expression, IDictionary<String, Object> htmlAttributes,
        String requiredMarker = "*")
    {
        return LabelHelper(html, ModelMetadata.FromLambdaExpression(expression, html.ViewData),
            ExpressionHelper.GetExpressionText(expression), null, htmlAttributes, requiredMarker);
    }

    public static MvcHtmlString LabelFor<TModel, TValue>(this HtmlHelper<TModel> html,
        Expression<Func<TModel, TValue>> expression, Object htmlAttributes, String requiredMarker)
    {
        return LabelFor(html, expression, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes), requiredMarker);
    }

    internal static MvcHtmlString LabelHelper(HtmlHelper html, ModelMetadata metadata, String htmlFieldName,
        String labelText = null, IDictionary<String, Object> htmlAttributes = null, String requiredMarker = null)
    {
        var resolvedLabelText = labelText ??
                                metadata.DisplayName ?? metadata.PropertyName ?? htmlFieldName.Split('.').Last();

        var tag = new TagBuilder("label");
        tag.Attributes.Add("for",
            TagBuilder.CreateSanitizedId(html.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(htmlFieldName)));
        tag.SetInnerText(resolvedLabelText);
        tag.MergeAttributes(htmlAttributes, true);

        if (metadata.IsRequired && !String.IsNullOrWhiteSpace(requiredMarker))
        {
            var requiredSpan = new TagBuilder("span") {InnerHtml = requiredMarker};
            requiredSpan.AddCssClass("required");

            tag.InnerHtml += requiredSpan;
        }

        var result = tag.ToString(TagRenderMode.Normal);

        return new MvcHtmlString(result);
    }
}

这里是单元测试

public static class LabelExtensionFixtures
{
    [TestFixture]
    public class should_return_label_with_required_info : MvcExtensionFixtureBase
    {
        private class TestClass
        {
            [Required]
            public Guid Id { get; set; }
        }

        private MvcHtmlString _expectedResult;
        private HtmlHelper<TestClass> _sut;
        private MvcHtmlString _result;

        [SetUp]
        public void Given()
        {
            //arrange
            _expectedResult =
                MvcHtmlString.Create(
                    "<label class=\"control-label col-md-2\" for=\"Id\">Id<span class=\"required\">*</span></label>");
            _sut = CreateHtmlHelper(new TestClass {Id = Guid.NewGuid()});

            //act
            _result = _sut.LabelFor(model => model.Id, new { @class = "control-label col-md-2" }, "*");
        }

        [Test]
        public void Test()
        {
            //asert
            Assert.That(_result.ToHtmlString(), Is.EqualTo(_expectedResult.ToHtmlString()));
        }
    }
}

public abstract class MvcExtensionFixtureBase
{
    protected HtmlHelper<T> CreateHtmlHelper<T>(T instance)
    {
        var viewDataDictionary = new ViewDataDictionary<T>(instance);
        var viewContext = A.Fake<ViewContext>();
        A.CallTo(() => viewContext.ViewData).Returns(viewDataDictionary);

        var viewDataContainer = A.Fake<IViewDataContainer>();
        A.CallTo(() => viewDataContainer.ViewData).Returns(viewDataDictionary);

        return new HtmlHelper<T>(viewContext, viewDataContainer);
    }
}

这篇关于C#html-helper扩展现有方法而不覆盖?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-14 06:57