9

I have a hyperlink with the navigate property set like this:

NavigateUrl='<%# Eval("My Text") %>'

How can I limit the string to 140 characters ? I have tried this Eval("My Text").ToString().Substring(0,140) but if the string length is less than 140 characters it throws an exception.

gdoron
  • 147,333
  • 58
  • 291
  • 367
Mario
  • 13,941
  • 20
  • 54
  • 110

6 Answers6

19

And yet an other possibility:

Eval("My Text").ToString().PadRight(140).Substring(0,140).TrimEnd()

Edit:

I do like LINQ, too:

Eval("My Text").ToString().Take(140).Aggregate("", (x,y) => x + y)
marapet
  • 54,856
  • 12
  • 170
  • 184
  • 1
    To avoid an `if (lenght > 140)` you use more memory and time. :) – Aristos Jan 21 '13 at 23:57
  • @Aristos I know, especially so if length is less than 140. But what's even worse: If the original string ("My Text") is less than 140 characters long _and_ contains trailing spaces, those trailing spaces get chopped off. I wouldn't recommend this solution if those spaces matter and if it were to be used everywhere and every bit of performance counts. Then again, as mentioned, it's just "yet an other possibility". And it's the shortest one on this page :-) – marapet Jan 22 '13 at 00:27
  • Just for play I make a speed test, your first function takes 20ms, your second 600ms, and Leniel takes 5ms (on 50000 compares); – Aristos Jan 22 '13 at 01:16
  • Come on, on **50000** compares you got 580ms difference? It's nothing!!! **If you care so much about performance start using c or even Assembly. C# isn't for micro-optimization. Period.** my +1. – gdoron Jan 22 '13 at 08:55
  • Is there way to avoid trim word in the middle, and trim before or after it? – Ahmad Z. Tibi Aug 23 '13 at 12:42
  • @AhmedYazanTibi I don't know what you mean by _trim word in the middle_. You may consider creating a new question with more details and examples. – marapet Aug 23 '13 at 14:06
4

Use It (:

< % # Eval("MyText").ToString().Length <= 30 ? Eval("MyText") : Eval("MyText").ToString().Substring(0, 30)+"..." % > 
Serdar KUŞ
  • 404
  • 1
  • 4
  • 16
3

Damn I like LINQ:

string.Concat('<%# Eval("My Text") %>'.ToString().Where((char, index) => index < 140))
gdoron
  • 147,333
  • 58
  • 291
  • 367
  • I like also what you have type - but how about the speed of it ? Isn't too much for a simple string length cut (and also slow ?) – Aristos Jan 21 '13 at 23:51
  • 1
    @Aristos, [Which is faster by Eric Lippert](http://ericlippert.com/2012/12/17/performance-rant/). – gdoron Jan 21 '13 at 23:53
  • Yes, Which is faster ? for sure the linq compile over a table with 20 lines is slower, because if its not static, then is compile 20 times to know that is need to just cut a string. – Aristos Jan 21 '13 at 23:55
  • @Aristos, the goal of the article which I hope you will read is: Do you really care? In this case I believe you don't, like in 99.99% of times. – gdoron Jan 21 '13 at 23:58
  • In talks everything sound philosophical nice - but I care about speed, and I care to make fast programs, I like to work with fast programs. linq is slow, make too many compiles in real time - if you use it too much, you end up with a slow program. :) – Aristos Jan 22 '13 at 00:01
  • @Aristos, then stop using LINQ, LINQ is the devil itself, the root of all slowness-LINQ. happy? :) – gdoron Jan 22 '13 at 00:03
  • :) you are sentimental :) nothing to do with real arguments... :) anyway. I say to you one more time - you have a linq inside a loop, that makes its much slow for a simple basic string cut. (its inside a loop because is use the `Eval` that declare that get the data from a database return.) – Aristos Jan 22 '13 at 00:06
  • @gdoron Are you sure this is working? In think `Join` needs a separator, and not sure about `char` being a valid name for the parameter. And last but not least, the OP seems to want to use it in a web form, so you probably can't wrap a `string.Join` around the eval statement (though not 100% sure about that...). I added a LINQ variant without `string.Join` to my answer. – marapet Jan 22 '13 at 01:00
  • @marapet, D'oh! I meant `string.Concat` not `string.join`, you're right. Fixed! And last but least, you can use LINQ and other methods with it. – gdoron Jan 22 '13 at 08:52
2

You can try the Truncate method as shown here:

C# Truncate String

Convert it to an extension method by simply adding the this keyword before the source parameter. It's a more convoluted approach but may be of value in cases where you need to reuse it somewhere else...

In your case, you'd have:

NavigateUrl='<%# Eval("My Text").ToString().Truncate(140) %>'

Complete console test app:

using System;

namespace ConsoleApplication2
{
    class Program
    {
        static void Main(string[] args)
        {
            string test1 = "A really big string that has more than 140 chars. This string is supposed to be trunctaded by the Truncate extension method defined in class StringTool.";

            Console.WriteLine(test1.Truncate(140));

            Console.ReadLine();
        }
    }

    /// <summary>
    /// Custom string utility methods.
    /// </summary>
    public static class StringTool
    {
        /// <summary>
        /// Get a substring of the first N characters.
        /// </summary>
        public static string Truncate(this string source, int length)
        {
            if (source.Length > length)
            {
                source = source.Substring(0, length);
            }
            return source;
        }

        /// <summary>
        /// Get a substring of the first N characters. [Slow]
        /// </summary>
        public static string Truncate2(this string source, int length)
        {
            return source.Substring(0, Math.Min(length, source.Length));
        }
    }
}

Output:

A really big string that has more than 140 chars. This string is supposed to be
trunctaded by the Truncate extension method defined in class
Leniel Maccaferri
  • 100,159
  • 46
  • 371
  • 480
0

Similar to Leniel's answer but with a twist.... Sometimes I like to append an ellipsis to demonstrate the displayed string has been truncated.

    /// <summary>
    /// Converts the value of the specified string to a truncated string representation
    /// </summary>
    /// <param name="source">The specified string</param>
    /// <param name="length">Integer specifying the maximum number of characters to retain from the specified string.</param>
    /// <param name="appendEllipsis">Determines whether or not to append an ellipsis to the truncated result.  If the specified string is shorter than the length parameter the ellipsis will not be appended in any event.</param>
    /// <returns>A truncated string representation of the specified string.</returns>
    public static String Truncate(this String source, int length, bool appendEllipsis = false)
    {
        if (source.Length <= length)
            return source;

        return (appendEllipsis)
            ? String.Concat(source.Substring(0, length), "...")
            : source.Substring(0, length);
    }
Steve
  • 198
  • 9
0

This worked for me - the truncate() function didn't pull up in my Visual Studio so I used Substring().

Text='<%# Eval("LastChangedTime", "{0:t}").ToString().Substring(0,10) %>'

This displays time to the nearest 1/10 of a second.

David Buck
  • 3,752
  • 35
  • 31
  • 35
George
  • 1