【问题标题】:The tag helper 'input' must not have C# in the element's attribute declaration area标签助手“输入”在元素的属性声明区域中不得包含 C#
【发布时间】:2020-03-07 23:48:11
【问题描述】:

我们在构建最近从 .NET Core 2.2 迁移到 3.0 的 ASP.NET Core MVC 应用程序时遇到以下错误:

标签助手“input”(或“textarea”或任何其他)不得具有 C# 在元素的属性声明区。

我们使用 Razor @functions 返回 HTML 属性内容以解决该问题,但是当您使用变量从函数返回它而没有任何额外逻辑时它看起来很丑(函数 dummy(htmlAttributeContent) 返回 htmlAttributeContent

@{
    var roAttrHTML = "";
    if (!user.GotAccessToken("someToken")) {
        roAttrHTML = " readonly=\"readonly\" ";
    }
}
<textarea class="testClass" asp-for="testId" @readonlyAttribute>@Model.Id</textarea>

实际上我们得到了错误

标签助手“textarea”的元素属性中不得包含 C# 申报区。

当编译我们的 ASP.NET Core MVC 应用程序时,我们需要找到方法(最好不使用@functions),这将为我们提供一种解决该问题的方法(因为我们有很多页面具有类似的逻辑,我们需要触摸一次,避免在未来 .NET Core 版本中支持属性的可能的新更改出现任何可能的问题)

【问题讨论】:

  • 你是如何定义@readonlyAttribute的?我在asp.net core 2.2中也会遇到同样的错误。为什么不试试readonly=@readonlyAttribute
  • @Rena 这应该是公认的答案!
  • @MDummy 实际上,什么都不做,因为readonly 属性的值无关紧要,一旦它在那里,该字段就是只读的

标签: model-view-controller razor asp.net-core-3.0


【解决方案1】:

我在创建新的 3.0 应用程序时遇到了同样的问题。一个旧的 2.2 应用程序允许我在声明中包含 C#,即使“它无效”1

我所做的是编写自己的 TagHelper2,使用以下步骤:

  1. 创建文件:CustomAttributeTagHelper .cs
namespace {YourBaseNameSpace}.Helpers.TagHelpers
{
    using System.Collections.Generic;
    using Microsoft.AspNetCore.Razor.TagHelpers;

    [HtmlTargetElement(Attributes = "custom-attributes")]
    public class CustomAttributeTagHelper : TagHelper
    {
        public Dictionary<string, string> CustomAttributes { get; set; }

        public override void Process(TagHelperContext context, TagHelperOutput output)
        {
            if (CustomAttributes != null)
                foreach (var pair in CustomAttributes)
                    if (!output.Attributes.ContainsName(pair.Key))
                        output.Attributes.Add(pair.Key, pair.Value);
        }
    }
}
  1. 修改:/Pages/Shared/_ViewImports.cshtml,在微软自己的@addTagHelper下面添加下面一行
@addTagHelper {YourBaseNameSpace}.Helpers.TagHelpers.*, {Your Assembly Name}

关键点:确保使用程序集名称,而不是上面逗号后的命名空间

2a。如果您不确定您的程序集名称是什么,请在您的 Program => Main(string[] args) 方法中运行以下代码:

Type t = typeof({YourBaseNameSpace}.Helpers.TagHelpers.CustomAttributeTagHelper);
string s = t.Assembly.GetName().Name.ToString();
Console.WriteLine($"The fully qualified assembly name you need is: {s}.");
  1. 然后您可以像在剃刀页面中一样简单地使用它:
@{
    Dictionary<string, string> myCustomAttributes = new Dictionary<string, string> {
        ["data-first-custom-attribute"] = "my custom value"
    };

    if (!user.GotAccessToken("someToken")) {
        myCustomAttributes.Add("readonly","readonly");
    }
}

<input custom-attributes="myCustomAttributes" />

注意:此代码可用于任何 TagHelper,这意味着您可以添加任何您喜欢的自定义属性。

如果您只想为单个属性(如上面的只读属性)创建它,那么您可以创建一个条件 TagHelper,它需要在构造时使用布尔值或作为其值。

【讨论】:

  • 真是头疼。
  • 这是解决这个问题的好方法。可以通过添加对通过匿名对象指定属性的支持来改进该类,使用 HtmlHelper.AnonymousObjectToHtmlAttributes(CustomAttributes);
【解决方案2】:

对于相同的问题,但具有多个属性,我做了以下解决方法:

@{
    //...
    string attributes = "...prepare attributes ...";
    string tag = "<input " + attributes + " />";
    <text>@Html.Raw(tag)</text>
    //...
}

@Html.Raw 不推荐,因为存在一些安全漏洞,但我还是在这里使用它。请注意这种风险。如果需要,我可以分享一些有关该风险的其他文章。否则,对于单个属性,我同意@Rena 的评论。

【讨论】:

    【解决方案3】:

    我最终删除了这条线

    @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers 
    

    来自 _ViewImports.cshtml

    在我的例子中,我必须非常精确地构建 html,而且我没有使用 TagHelpers。

    【讨论】:

      【解决方案4】:

      如果您不需要使用 TagHelper,您可以使用&lt;!elementName&gt; 为特定元素禁用它:

      <!textarea class="testClass" asp-for="testId" @readonlyAttribute>@Model.Id</!textarea>
      

      请参阅@glenn223's answer 以获得更结构化的解决方案。通过添加对匿名对象的支持,我改进了他的解决方案:

      using Microsoft.AspNetCore.Mvc.ViewFeatures;
      using Microsoft.AspNetCore.Razor.TagHelpers;
      
      namespace  {YourBaseNameSpace}.Helpers.TagHelpers
      {
          [HtmlTargetElement(Attributes = "custom-attributes")]
          public class CustomAttributesTagHelper : TagHelper
          {
              public object CustomAttributes { get; set; }
      
              public override void Process(TagHelperContext context, TagHelperOutput output)
              {
                  var customAttributesDictionary = HtmlHelper.AnonymousObjectToHtmlAttributes(CustomAttributes);
                  foreach (var (key, value) in customAttributesDictionary)
                  {
                      output.Attributes.SetAttribute(key, value);
                  }
              }
          }
      }
      

      【讨论】:

        【解决方案5】:

        你可以这样做:

        @if (!user.GotAccessToken("someToken")) 
        {
           <textarea class="testClass" asp-for="testId" readonly>@Model.Id</textarea>
        }
        else
        {
           <textarea class="testClass" asp-for="testId">@Model.Id</textarea>
        }
        

        【讨论】:

          【解决方案6】:

          根据文档,您可以在 ASP .NET 5.0 中这样做

          <input asp-for="LastName" 
                 disabled="@(Model?.LicenseId == null)" />
          

          https://docs.microsoft.com/en-us/aspnet/core/mvc/views/tag-helpers/intro?view=aspnetcore-5.0#c-in-tag-helpers-attributedeclaration

          【讨论】:

            【解决方案7】:

            我遇到了同样的问题,但我有一个简单的解决方案:

            引发错误的代码:

            <select asp-for="Journeys.VehicleType" class="test" style="width: 100%;" id="vehicleType" @disabled>
            

            有效的代码:

            <select @disabled asp-for="Journeys.VehicleType" class="test" style="width: 100%;" id="vehicleType">
            

            为了让我的 IDE 不会抛出错误,我所做的只是将 @disabled 属性移到“asp-for”属性的前面。

            也适用于普通输入字段:

            引发错误的代码:

            <input  type="datetime-local" asp-for="Journeys.StartTime" @disabled id="startTime"/>
            

            有效的代码:

             <input @disabled type="datetime-local" asp-for="Journeys.StartTime" id="startTime"/>
            

            信息:@disabled 只是一个包含空字符串或“禁用”的变量:

            var disabled = "";   
            if (Model.Disabled)
            {
                disabled = "disabled";       
            }
            

            希望这能帮助一些有同样问题的人。

            【讨论】:

              猜你喜欢
              • 2022-10-01
              • 2020-02-08
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2019-11-26
              • 2023-04-03
              • 2020-07-07
              相关资源
              最近更新 更多