Ответ 1
string dec = "description";
string result = dec.Substring( 0, dec.Length > 240 ? 240 : dec.Length )
У меня есть ретранслятор, который отображает данные из моей таблицы проектов. Есть projectId, имя и описание. Я использую подстроку (1, 240) для описания. Но иногда строка короче 240, поэтому я получаю ArgumentOutOfRangeException. Можете ли вы рассказать мне, как отображать весь текст, если я получу исключение. Это мой код.
<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" runat="server">
<asp:Panel ID="pnlDisplayProjects" runat="server" Visible="true">
<center><h2><b>Проекти</b></h2></center>
<asp:Repeater ID="rptrProjects" runat="server">
<HeaderTemplate>
<table border="1" cellpadding="2" cellspacing="2" align="center" width="80%" style="background-color:#F7F6F3;">
</HeaderTemplate>
<ItemTemplate>
<tr>
<td align="left" style="width:40px">
<asp:Label ID="LblProjectId" runat="server" Text='<%# Eval("ProjectID") %>' />
</td>
<td align="center">
<asp:Label ID="LblName" runat="server" Text='<%# Eval("Name") %>' />
</td>
</tr>
<tr>
<td colspan="2">
<asp:Label ID="LblDescription" runat="server" Text='<%# Eval("Description").ToString().Substring(1, 240) + "..." %>'/>
<asp:HyperLink ID="HlMore" runat="server" NavigateUrl='<%#"~/Project/ViewProject.aspx?projectId=" + Eval("ProjectID") %>' Text="More" />
</td>
</tr>
</ItemTemplate>
<FooterTemplate>
</table>
</FooterTemplate>
</asp:Repeater>
</asp:Panel>
protected override void OnPreRender(EventArgs e)
{
var table = Projects.GetTableWithProjects();
if (table.Rows.Count > 0)
{
rptrProjects.DataSource = table;
rptrProjects.DataBind();
}
else
{
pnlDisplayProjects.Visible = false;
Master.PrintMessage("There are no projects.");
}
}
string dec = "description";
string result = dec.Substring( 0, dec.Length > 240 ? 240 : dec.Length )
Я бы посоветовал вам написать отдельный метод расширения, если вы используете .NET 3.5. Что-то вроде этого:
public static string SafeSubstring(this string text, int start, int length)
{
return text.Length <= start ? ""
: text.Length - start <= length ? text.Substring(start)
: text.Substring(start, length);
}
В принципе, версия Substring
, которая никогда не будет генерировать исключение, если только начало или длина не являются отрицательными (в этом случае я не знаю, что он мог бы разумно вернуть).
Вы бы назвали это следующим образом:
Eval("Description").ToString().SafeSubstring(1, 240) + "..."
Недостатком этого является то, что он будет включать в себя многоточие (...), даже если он вообще не урезал строку...
description.Substring(0, Math.Min(description.Length, 240));
Метод расширения:
public static string SafeSubstring(this string text, int start, int length)
{
if (start >= text.Length)
return "";
if (start + length > text.Length)
length = text.Length - start;
return text.Substring(start, length);
}
Основываясь на ответе Джона Скита, я думаю, что он должен проверять значение null, иначе это не совсем безопасный метод:)
public static string SafeSubstring(this string text, int start, int length)
{
if (text == null) return null;
return text.Length <= start ? ""
: text.Length - start <= length ? text.Substring(start)
: text.Substring(start, length);
}
Вы можете использовать LINQ, как показано ниже:
string someString = "abcde";
string subStr = string.Join("", someString.Take(240));
Я бы написал статическую вспомогательную функцию или метод расширения.
public static string SafeSubstring(string str, int start, int count){
int n = str.Length;
return str.Substring(Math.Min(start,n), Math.Min(count,n));
}
Затем используйте:
<%# SafeSubstring(Eval("Description",""), 1, 240) %>
(И если вы также хотите быть в безопасности для отрицательных целых чисел, бросьте туда Math.Max
с 0).
Это немного взломанный, но самый простой способ - изменить:
Eval("Description").ToString().Substring(1,240)
к
Eval("Description").ToString().PadRight(240).Substring(1, 240)
Я не уверен в соображениях производительности на этом, хотя, если у них много элементов.
Если по какой-либо причине вы НЕОБХОДИЛИ 240 символов в этом месте, вы можете отбросить это поле, выходящее из базы данных, как char(241)
, и в этом случае оно всегда будет 241 символом, а отступом вправо, если содержимое поле было короче 241 символа. Затем вы можете удалить первый символ с помощью Substring(1, 240)
, как сейчас.
Хотя, я должен задаться вопросом, не хотите ли вы сделать Substring(0, 240)
, который бы не выдавал исключение, если строка была короче 240 символов и начиналась с начала строки, а не на втором характер.
Другой вариант - написать метод, который вы называете так, чтобы ваш eval превратился в:
<%# GetString(Container.DataItem) %>
Итак, в методе, который вы можете проверить, чтобы убедиться, что элемент НЕ является нулевым, потому что вы можете бомбить вызов .ToString в элементе NULL. Затем вы можете оценить элемент контейнера и передать длину подстроке.
Text='<%# Eval("Description").ToString().Substring(1, Math.Min(240, Eval("Description").ToString().Length - 1)) + "..." %>'
Попробуйте сохранить это просто...
Нам нужно только обрезать до заданной максимальной длины, так как мы называем это тем, что это такое:
description.TruncateTo(240);
Метод расширения, который позволяет использовать вышеперечисленное (эллипсис добавляется по умолчанию при усечении):
public static class StringExtensions
{
public static string TruncateTo(this string val, int maxLength, bool ellipsis = true)
{
if (val == null || val.Length <= maxLength)
{
return val;
}
ellipsis = ellipsis && maxLength >= 3;
return ellipsis ? val.Substring(0, maxLength - 3) + "..." : val.Substring(0, maxLength);
}
}