2010-01-07 6 views
20

Tengo un repetidor que muestra datos de mi tabla de proyectos. Hay projectId, nombre y descripción. Yo uso Subcadena (1, 240) en la descripción. Pero a veces la cadena es más corta que 240, entonces obtengo ArgumentOutOfRangeException. ¿Me puede decir cómo mostrar todo el texto si recibo la excepción? Este es mi códigoProblema con la subcadena() - 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."); 
     } 
    } 

Respuesta

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

¿Cómo lo llamo? –

+0

Gracias. Lo hice :) –

+3

Solo un chequeo de cordura - 'SubString' debería ser' Substring', ¿verdad? – brandaemon

0

Es un poco de un truco, pero el método más simple sería la de cambiar:

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

a

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

No estoy seguro acerca de las consideraciones de rendimiento en esto, sin embargo, si hay muchos elementos.

31

Le sugiero que escriba un método de extensión diferente si está utilizando .NET 3.5. Algo como esto:

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

Básicamente eso es una versión de Substring que nunca será una excepción a menos de inicio o la longitud es negativa (en cuyo caso no sé lo que podría volver con sensatez).

Usted lo llamaría así:

Eval("Description").ToString().SafeSubstring(1, 240) + "..." 

La desventaja de esto es que va a incluir los puntos suspensivos (...) incluso si no es en realidad trunca la cadena en todo ...

+0

@Phil: ¿Te importa dar un ejemplo que falla? Solo "sospecho que esto no funciona" no es particularmente útil. (Acabo de solucionar un par de problemas.) –

+0

No debería estar revisando si el texto es nulo. De lo contrario, este método 'seguro' arrojará! – superlogical

+1

@superlogical: Bueno, depende de cómo quiera que se comporte. Es "seguro" en términos del índice. Probablemente verifique si 'text' es nulo, pero solo para arrojar' ArgumentNullException' en su lugar :) –

0

Si REQUIERE 240 caracteres en ese lugar por algún motivo, puede convertir el campo que sale de la base de datos como char(241) en cuyo caso siempre será de 241 caracteres, con relleno a la derecha si el contenido del campo fue más corto de 241 caracteres. Entonces todavía puedes quitar el primer personaje con el Substring(1, 240) como lo estás ahora.

Aunque, me pregunto si no desea hacer un Substring(0, 240) que no arrojaría una excepción si la cadena tuviera menos de 240 caracteres, y comenzaría al principio de la cadena, en lugar del segundo carácter .

+0

Intenté Subcadena (0, 240) pero aún sigue una excepción. –

0

Otra opción es escribir aa método que se llama por lo que su eval convierte en:

<%# GetString(Container.DataItem) %> 

Así que en el método se puede comprobar para asegurarse de que el artículo no es nulo, ya que puede bombardear a cabo la llamada. ToString en un elemento NULL. Luego puede evaluar el elemento contenedor y pasar la longitud a la llamada subserie.

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

un método de extensión:

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

que iba a escribir un método de función auxiliar o la extensión estática.

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

A continuación, utilice:

<%# SafeSubstring(Eval("Description",""), 1, 240) %> 

(Y si también desea ser seguro para los enteros negativos, arrojar algo de Math.Max 's con 0 en ese país.)

3

Sobre la base de la respuesta de Jon Skeet , Creo que debería estar buscando nulo o de lo contrario no es exactamente un método seguro :)

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

. Los métodos de la biblioteca .net generalmente no comprueban nulos, simplemente explotan con una excepción si pasa uno. Es responsabilidad de quienes llaman verificar y deben comportarse de manera similar por coherencia. – samosaris

2

Y ou puede utilizar LINQ de la siguiente manera:

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

Nota, este método va a ser más ineficiente debido a la conversión de cadena a chararray (es decir, copia), luego Take() y luego volver a cadena. Subcadena salta internamente el paso intermedio. – enorl76

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

Vamos a tratar de mantener este sencillo ...

Tan sólo hay que truncar a una longitud máxima determinada, así que ¿qué le llamamos lo que es :

description.TruncateTo(240); 

el método de extensión que permite el anterior (puntos suspensivos se añade por defecto si truncado):

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