Не удалось найти тип или имя пространства имен TemplateBuilder после обновления до. Net core 3.1 - PullRequest
0 голосов
/ 12 марта 2020

Я переношу веб-приложение, из которого я не создал. Net Core 2.2 на. Net Core 3.1. После миграции мне удалось исправить все проблемы, кроме той, которая связана с TemplateBuilder как Microsoft.AspNetCore. Mvc .ViewFeatures.Internal больше не доступен в. Net Core 3.1.

Есть класс в проекте, который переопределяет метод «Process» TagHelper для реализации некоторой обобщенной c validation. Добавляет некоторую проверку, а затем генерирует измененную HTML, используя метод Microsoft.AspNetCore. Mvc .ViewFeatures.Internal.TemplateBuilder.

    public override void Process(TagHelperContext context, TagHelperOutput output)
    {
        if (context == null)
        {
            throw new ArgumentNullException(nameof(context));
        }

        if (output == null)
        {
            throw new ArgumentNullException(nameof(output));
        }

        //clear the output
        output.SuppressOutput();

        //container for additional attributes
        var htmlAttributes = new Dictionary<string, object>();
        var attributes = context.AllAttributes;
        foreach (var attribute in attributes)
        {
            if (!attribute.Name.Equals(ForAttributeName) &&
                !attribute.Name.Equals(RenderFormControlClassAttributeName) &&
                !attribute.Name.Equals(TemplateAttributeName) &&
                !attribute.Name.Equals(DisabledAttributeName) &&
                !attribute.Name.Equals(RequiredAttributeName) &&
                !attribute.Name.Equals(PostfixAttributeName) &&
                !attribute.Name.Equals(ValueAttributeName) &&
                !attribute.Name.Equals(PlaceholderAttributeName) &&
                !attribute.Name.Equals(InputIdAttributeName) &&
                !attribute.Name.Equals(RemoveMaxLengthAttributeName))
            {
                htmlAttributes.Add(attribute.Name, attribute.Value);
            }
        }

        bool.TryParse(RemoveMaxLength, out bool removeMaxLength);
        if (!removeMaxLength)
        {
            htmlAttributes.Add("maxlength", "75");
        }
        //set placeholder if exists
        if (!string.IsNullOrEmpty(Placeholder))
            htmlAttributes.Add("placeholder", Placeholder);

        //set value if exists
        if (!string.IsNullOrEmpty(Value))
            htmlAttributes.Add("value", Value);

        //disabled attribute
        bool.TryParse(IsDisabled, out bool disabled);
        if (disabled)
        {
            htmlAttributes.Add("disabled", "disabled");
        }

        if (!string.IsNullOrEmpty(InputId))
        {
            htmlAttributes.Add("id", InputId);
        }

        //required asterisk
        bool.TryParse(IsRequired, out bool required);
        if (required)
        {
            output.PreElement.SetHtmlContent("<div class='input-group input-group-required'>");
            output.PostElement.SetHtmlContent("<div class=\"input-group-btn\"><span class=\"required\">*</span></div></div>");
        }

        //contextualize IHtmlHelper
        var viewContextAware = _htmlHelper as IViewContextAware;
        viewContextAware?.Contextualize(ViewContext);

        //add form-control class
        bool.TryParse(RenderFormControlClass, out bool renderFormControlClass);
        if (string.IsNullOrEmpty(RenderFormControlClass) && For.Metadata.ModelType.Name.Equals("String") || renderFormControlClass)
            htmlAttributes.Add("class", "form-control");

        //generate editor

        //we have to invoke strong typed "EditorFor" method of HtmlHelper<TModel>
        //but we cannot do it because we don't have access to Expression<Func<TModel, TValue>>
        //more info at https://github.com/aspnet/Mvc/blob/dev/src/Microsoft.AspNetCore.Mvc.ViewFeatures/ViewFeatures/HtmlHelperOfT.cs

        //so we manually invoke implementation of "GenerateEditor" method of HtmlHelper
        //more info at https://github.com/aspnet/Mvc/blob/dev/src/Microsoft.AspNetCore.Mvc.ViewFeatures/ViewFeatures/HtmlHelper.cs

        //little workaround here. we need to access private properties of HtmlHelper
        //just ensure that they are not renamed by asp.net core team in future versions
        var viewEngine = CommonHelper.GetPrivateFieldValue(_htmlHelper, "_viewEngine") as IViewEngine;
        var bufferScope = CommonHelper.GetPrivateFieldValue(_htmlHelper, "_bufferScope") as IViewBufferScope;
        var templateBuilder = new TemplateBuilder(
            viewEngine,
            bufferScope,
            _htmlHelper.ViewContext,
            _htmlHelper.ViewData,
            For.ModelExplorer,
            For.Name,
            Template,
            readOnly: false,
            additionalViewData: new { htmlAttributes, postfix = Postfix });

        var htmlOutput = templateBuilder.Build();
        output.Content.SetHtmlContent(htmlOutput.RenderHtmlContent());
    }

Я пытался найти любую альтернативу Microsoft.AspNetCore. Mvc .ViewFeatures.Internal.TemplateBuilder, но не удалось.

1 Ответ

0 голосов
/ 12 марта 2020

Этот конкретный пробел как часть aspnet / Mvc # 8724 . 3.0 предлагает тип ModelExpressionProvider, который доступен из DI, и объединяет 3 ранее доступных API:

ModelExpressionProvider.GetExpressionText<TModel, TValue>(Expression<Func<TModel, TValue>>)
ModelExpressionProvider.CreateModelExpression<TModel, TValue>(ViewDataDictionary<TModel>, string expression)
ModelExpressionProvider.CreateModelExpression<TModel, TValue>(ViewDataDictionary<TModel>, Expression<Func<TModel, TValue>> expression)

Последние два возвращают экземпляр ModelExpression, который является надмножеством для ModelExplorer, который возвращает ExpressionMetadataProvider.

В ASP. NET Базовые, публичные типы - это типы, которые объявлены как publi c, но вставлены в Internal namespace. Хотя эти типы опубликованы c, они не имеют политики поддержки и подвержены критическим изменениям. К сожалению, случайное использование этих типов было обычным явлением, что приводило к критическим изменениям в этих проектах и ​​ограничивало нашу способность поддерживать платформу.

В ASP. NET Core 3.1, Microsoft обновляет все публичные типы в MVC должен быть опубликован c в поддерживаемом пространстве имен или внутренним в зависимости от ситуации. Это включает типы в следующих пространствах имен:

Microsoft.AspNetCore.Mvc.ViewFeatures.Internal
...