Подтвердить что ты не робот

Проблема с Substring() - ArgumentOutOfRangeException

У меня есть ретранслятор, который отображает данные из моей таблицы проектов. Есть 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.");
        }
    }
4b9b3361

Ответ 1

string dec = "description";
string result = dec.Substring( 0, dec.Length > 240 ? 240 : dec.Length )

Ответ 2

Я бы посоветовал вам написать отдельный метод расширения, если вы используете .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) + "..."

Недостатком этого является то, что он будет включать в себя многоточие (...), даже если он вообще не урезал строку...

Ответ 3

description.Substring(0, Math.Min(description.Length, 240));

Ответ 4

Метод расширения:

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);
}

Ответ 5

Основываясь на ответе Джона Скита, я думаю, что он должен проверять значение 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);
}

Ответ 6

Вы можете использовать LINQ, как показано ниже:

string someString = "abcde"; 
string subStr = string.Join("", someString.Take(240));

Ответ 7

Я бы написал статическую вспомогательную функцию или метод расширения.

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).

Ответ 8

Это немного взломанный, но самый простой способ - изменить:

Eval("Description").ToString().Substring(1,240)

к

Eval("Description").ToString().PadRight(240).Substring(1, 240)

Я не уверен в соображениях производительности на этом, хотя, если у них много элементов.

Ответ 9

Если по какой-либо причине вы НЕОБХОДИЛИ 240 символов в этом месте, вы можете отбросить это поле, выходящее из базы данных, как char(241), и в этом случае оно всегда будет 241 символом, а отступом вправо, если содержимое поле было короче 241 символа. Затем вы можете удалить первый символ с помощью Substring(1, 240), как сейчас.

Хотя, я должен задаться вопросом, не хотите ли вы сделать Substring(0, 240), который бы не выдавал исключение, если строка была короче 240 символов и начиналась с начала строки, а не на втором характер.

Ответ 10

Другой вариант - написать метод, который вы называете так, чтобы ваш eval превратился в:

<%# GetString(Container.DataItem) %>

Итак, в методе, который вы можете проверить, чтобы убедиться, что элемент НЕ является нулевым, потому что вы можете бомбить вызов .ToString в элементе NULL. Затем вы можете оценить элемент контейнера и передать длину подстроке.

Ответ 11

Text='<%# Eval("Description").ToString().Substring(1, Math.Min(240, Eval("Description").ToString().Length - 1)) + "..." %>'

Ответ 12

Попробуйте сохранить это просто...

Нам нужно только обрезать до заданной максимальной длины, так как мы называем это тем, что это такое:

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);
    }
}