web-dev-qa-db-ja.com

ASP.NET 5 MVC 6のTagBuilder InnerHtml

Beta7の時点でTagBuilderに重大な重大な変更があり、アナウンスメントリポジトリでそれらについて言及していないように思えます。

具体的には、.ToStringはタグビルダーをレンダリングせず、タイプの名前を返すだけです。以前は、HtmlHelper拡張機能内で次のようなことを実行して、ネストされたhtml要素を構築できました。

var li = new TagBuilder("li");
li.AddCssClass("inactive");
var span = new TagBuilder("span");
span.SetInnerText(somestring);
li.InnerHtml = span.ToString();

.InnerHtmlはIHtmlContentになったため、文字列を受け入れなくなりました

ただし、.ToString()はタグをレンダリングしないため、これも機能しません。

li.InnerHtml = new HtmlString(span.ToString())

タイプの名前である「Microsoft.AspNet.Mvc.Rendering.TagBuilder」として表示されるだけです。

TagBuilderには、必要な機能を提供する新しいメソッドはありません。私は何が欠けていますか? TagBuilderで複雑なネストされたHTMLを今すぐ構築するにはどうすればよいですか?

18
Joe Audette

TagBuilderIHtmlContentを実装するようになったため、.ToString()を実行せずに直接使用できるはずです。

var li = new TagBuilder("li");
li.AddCssClass("inactive");
var span = new TagBuilder("span");
span.SetInnerText(somestring);
li.InnerHtml = span;

Beta 7の現在の実装に伴う実際の問題は、2つの子タグビルダーコンテンツを親に追加する簡単な方法がないことです。 GitHub の議論をフォローできます。

現在の提案では、InnerHtmlを割り当て不可にしますが、代わりにAppendをサポートします。これは、ベータ8で実装することを目的としています。

ベータ7の回避策は、StringWriterparent.WriteToを呼び出してstringに変換することです。 。

執筆時点でMVC 6を使用して、Tagbuiler.InnerHtmlには、実際にはもうセッターがありません。代わりに、要素を追加するいくつかのメソッドがあります。たとえば、次のように書くことができます。

var container = new TagBuilder("div");
var input = new TagBuilder("input");

container.InnerHtml.AppendHtml(input);
16
Memet Olsen

@Mihaiの回答に基づいて、StringWriterアプローチの実際のコードを示します。

// Create tag builder
var builder = new TagBuilder("img");
//...
// Render tag approach also changed in .NetCore
builder.TagRenderMode = TagRenderMode.SelfClosing;

//Create the StringWriter and make TagBuilder "WriteTo" it
var stringWriter = new System.IO.StringWriter();
builder.WriteTo(stringWriter, HtmlEncoder.Default);
var tagBuilderIsFinallyAStringNow = stringWriter.ToString();
3
goamn

@メメット・オルセン

すべてのカスタムTagHelpersは、4.6.1(1.0.0-rc2)へのアップデートで壊れました。 InnerHtml.Append()はTagBuilderを受け入れなくなります。

代わりに、AppendHtml()メソッドを使用する必要があります。

var container = new TagBuilder("div");
var input = new TagBuilder("input");

container.InnerHtml.AppendHtml(input);

2番目のバグ修正 [here]

3
Paul McCombie

ベータ8では、タグヘルパーにAppend()メソッドを追加することでこの問題を解決しました。

ベータ7の場合、解決策はBufferedHtmlContent()クラスを使用することですが、アクセスできないため、追加の作業を行う必要があります。

private class MyBufferedHtmlContent : IHtmlContent
{
    internal List<IHtmlContent> Entries { get; } = new List<IHtmlContent>();

    public MyBufferedHtmlContent Append(IHtmlContent htmlContent)
    {
        Entries.Add(htmlContent);
        return this;
    }

    public void WriteTo(TextWriter writer, IHtmlEncoder encoder)
    {
        foreach (var entry in Entries)
        {
            entry.WriteTo(writer, encoder);
        }
    }
}

使用法:

TagBuilder firstChild = new TagBuilder("input");
firstChild.MergeAttribute("type", "hidden");
firstChild.MergeAttribute("name", "Ids");
firstChild.TagRenderMode = TagRenderMode.SelfClosing;

TagBuilder secondChild = new TagBuilder("input");
secondChild.MergeAttribute("type", "hidden");
secondChild.MergeAttribute("name", "Ids");
secondChild.TagRenderMode = TagRenderMode.SelfClosing;

var innerHtml = new MyBufferedHtmlContent();
innerHtml.Append(firstChild);
innerHtml.Append(secondChild);
TagBuilder parent = new TagBuilder("div");
parent.InnerHtml = innerHtml;
2

span.SetInnerText(somestring);を失ったので

span.InnerHtml.SetContent(somestring);

Microsoft.AspNetCore.Html.HtmlContentBuilderExtensionsを使用します。

これは、AspNetCore 2.0.1の4.7の観点から来ています。

2
A James