Substring()的问题 - ArgumentOutOfRangeException

时间:2010-01-07 15:43:33

标签: c# asp.net

我有一个转发器,显示我的Projects表中的数据。有projectId,名称和描述。我在描述中使用了Substring(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.");
        }
    }

12 个答案:

答案 0 :(得分:35)

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

答案 1 :(得分:35)

如果您使用的是.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) + "..."

这样做的缺点是它会包含省略号(...),即使它实际上并没有截断字符串......

答案 2 :(得分:11)

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

答案 3 :(得分:3)

扩展方法:

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

答案 4 :(得分:3)

根据Jon Skeet的回答,我认为它应该检查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);
}

答案 5 :(得分:2)

我会写一个静态辅助函数或扩展方法。

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

(如果你还想对负整数保持安全,那么在那里抛出一些带有0的Math.Max。)

答案 6 :(得分:2)

您可以使用LINQ,如下所示:

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

答案 7 :(得分:1)

这有点像黑客,但最简单的方法是改变:

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

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

我不确定这方面的性能考虑,但是,如果有很多项目。

答案 8 :(得分:0)

如果由于某种原因需要在该位置使用240个字符,则可以将来自数据库的字段转换为char(241),在这种情况下,它将始终为241个字符,如果内容填充到右侧该字段短于241个字符。然后你仍然可以像现在一样用Substring(1, 240)剥离第一个角色。

虽然,我一定不知道你是不是想要做Substring(0, 240)如果字符串短于240个字符就不会抛出异常,并且会从字符串的开头开始,而不是第二个角色。

答案 9 :(得分:0)

另一种选择是编写一个你调用的方法,这样你的eval变成了:

<%# GetString(Container.DataItem) %>

因此,在方法中,您可以检查以确保该项为非null,因为您可能会在NULL项目上弹出.ToString。然后,您可以评估容器项并将长度传递给子字符串调用。

答案 10 :(得分:0)

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

答案 11 :(得分:0)

让我们试着保持这个简单......

我们只需截断到给定的最大长度,那么我们如何称它为它:

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