Запретить asp: заполнителю удалять пробелы

#asp.net #whitespace

#asp.net #пробелы

Вопрос:

Я столкнулся с некоторым странным поведением asp:PlaceHolder , оно удаляет пробелы между asp:Literal символами внутри него.

Например, для этого кода:

 <asp:PlaceHolder ID="PlaceHolder1" runat="server">
    <asp:Literal ID="Literal1" Text="aa" runat="server"></asp:Literal>
    <asp:Literal ID="Literal2" Text="bb" runat="server"></asp:Literal>
</asp:PlaceHolder>
<asp:Literal ID="Literal3" Text="cc" runat="server"></asp:Literal>
<asp:Literal ID="Literal4" Text="dd" runat="server"></asp:Literal>
  

Результат будет aabb cc dd .

Есть ли способ помешать ему удалять пробелы (а не путем добавления amp;nbsp; между литералами или Text="aa " )?

Комментарии:

1. зачем вам это нужно? в будущем вам и другим пользователям будет намного сложнее выполнить рефакторинг

2. @Kim Я хочу этого, потому что именно так это должно работать. Если литералами являются имя и фамилия, я хочу, чтобы между ними был пробел…

3. Просто столкнулся с этим и чуть не вырвал себе волосы. Я не смог воспроизвести на чистом новом веб-сайте, поэтому я начал удалять теги, пока не определил заполнитель как виновника. После этого было легко найти этот пост. Я все еще не понимаю, почему это вообще могло быть разработано таким образом, предполагая, что это не ошибка.

4. connect.microsoft.com/VisualStudio/feedback/details/386790/… «Спасибо за отчет, на самом деле это сделано намеренно. Заполнитель обычно не используется пользователем в такой разметке, по сути, это «маркер» на странице …» Итак, если это ПРОСТО маркер, зачем удалять пробелы? Я все еще не понимаю…

5. @NelsonRothermel Из ответа @pOcHa видно, что это сделано намеренно. Посмотрите на AllowWhitespaceLiterals переопределение в PlaceHolderControlBuilder . Все еще не уверен, почему он разработан таким образом…

Ответ №1:

Самое элегантное решение — просто переопределить PlaceHolder :

 using System.Web.UI;
using System.Web.UI.WebControls;

namespace CustomControls
{
    [ToolboxData("<{0}:Holder ID='Holder1' runat='server'></{0}:Holder>"), ControlBuilder(typeof(ControlBuilder))]
    public sealed class Holder: PlaceHolder
    {
    }
}
  

Ключевым моментом здесь является использование ControlBuilder вместо PlaceHolderControlBuilder , которое просто переопределяет его, чтобы всегда возвращать false for AllowWhiteSpaceLiterals .

Вы используете его как любой другой веб-элемент управления:

 <%@ Register TagPrefix="asp" Namespace="CustomControls" %>
<asp:Holder runat="server">...</asp:Holder>
  

Ответ №2:

Я придумал два решения:

Сначала: заменить asp:PlaceHolder на asp:Panel . Недостатком является то, что вы получаете перенос div .

Второе: поместить пустой HTML-комментарий между literals

 <asp:PlaceHolder ID="PlaceHolder1" runat="server">
    <asp:Literal ID="Literal1" Text="aa" runat="server"></asp:Literal><!>
    <asp:Literal ID="Literal2" Text="bb" runat="server"></asp:Literal>
</asp:PlaceHolder>
  

И да, <!> это легальный HTML-комментарий.

Комментарии:

1. для реального решения взгляните на мой ответ

Ответ №3:

Я бы либо окружил его символом a, либо использовал asp: label вместо литерала. У вас было бы намного больше контроля над тем, как он будет использоваться. С помощью span — присвоите ему класс или идентификатор, и вы сможете настроить его так, чтобы он выглядел так, как вам нравится.

В качестве альтернативы создайте свой собственный литерал. Это было бы не так сложно, но вы могли бы пропустить некоторые другие материалы, которые поставляются с ним.

Третья альтернатива — создать промежуточную строку, которую вы можете привязать к литералу / использовать в качестве входных данных в литерал. Это позволило бы получить aa bb в гарантированном формате.

Комментарии:

1. С asp:Label у нас та же проблема, в любом случае я предпочитаю не добавлять дополнительные элементы в HTML.