Displaying The First n Characters Of Text

Displaying the first n characters of a block of text on a page without chopping words off halfway through is a common requirement. There are a number of ways to achieve this, but here's an extension method that you might find useful.

public static class StringExtensions
{
  /// <summary>
  /// Returns part of a string up to the specified number of characters, while maintaining full words
  /// </summary>
  /// <param name="s"></param>
  /// <param name="length">Maximum characters to be returned</param>
  /// <returns>String</returns>
  public static string Chop(this string s, int length)
  {
    if (String.IsNullOrEmpty(s))
      throw new ArgumentNullException(s);
    var words = s.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
    if (words[0].Length > length)
      return words[0];
    var sb = new StringBuilder();

    foreach (var word in words)
    {
      if ((sb + word).Length > length)
        return string.Format("{0}...", sb.ToString().TrimEnd(' '));
      sb.Append(word + " ");
    }
    return string.Format("{0}...", sb.ToString().TrimEnd(' '));
  }
}

In case you didn't know, an Extension method is one that appears to endow an existing type with additional methods. In this case, the type is System.String. The String type already comes with a large number of methods, together with an array of extensions methods provided by the .NET framework developers. Extension methods are static methods, which are called in the same way as instance methods although you don't instantiate an instance of the object that the method acts upon. The type that an extension method extend is denoted by the first parameter, and it's preceded by the this keyword. Here are some example of how to use this extension method:


[Razor]

@myString.Chop(50)



[MVC in a Web Forms View]

<%= ViewData["myString"].ToString().Chop(50) %>



[Web Forms in an ItemTemplate]

<ItemTemplate>
   <asp:Label ID="Label1" runat="server" Text='<%# Eval("myString").ToString().Chop(50) %>' />
</ItemTemplate>

A quick explanation about the body of the method itself - as I mentioned, the first parameter is the type which is intended to be extended, and the second is the maximum number of characters to be displayed. All the words in the string that this method acts on are placed as individual items in an array by the String.Split() method. StringSplitOptions.RemoveEmptyEntries ensures that if there are double spaces, they will not be treated as words and added to the array as elements. The array is iterated over in a foreach loop, and elements are added to a StringBuilder object (together with a space after each element or word). The LINQ expression checks the current length of the StringBuilder's contents on each iteration to ensure that the maximum length specified in the parameter is not exceeded. Finally, the result has the last trailing space removed (TrimEnd()), and is returned.

Date Posted:
Last Updated:
Posted by:
Total Views to date: 30326

15 Comments

- Robert

Great extension. I added this method to my class with string extensions. Thanks

- Samuel

Very nice trick.

- Sinden

I've been banging my head around a way to do this and got tied up in attempting to use Regex for it and it's as simple as this!

I don't know whether to be annoyed or grateful to you!

- Pham Anh

Thanks you! Sharing

- Javier

Thanks Mike for sharing this code. I added a little 'tidbit' that makes the dots appear ONLY if the string is indeed truncated. Say I have two strings, one is 25 characters and the other 50. My "Chop" is set at 40, so in the case of the 25 character string I don't want to see the dots, but in the 50 character string I do.

I had trouble posting the code here (for good reason, I don't think this form allows markup), so I've posted it as a follow-up to a post at the ASP.NET forums. Follow this link: http://forums.asp.net/t/1646631.aspx

Hope that helps someone out there.
Thanks again Mike for this great resource and all your code samples.

- Anooj

Shouldn't it be
if ((sb + word).Length > length)
instead of
if ((sb + word).Length + word.Length > length)
to get the desired result.

Anyways,it's a nice piece of code....

- Mike

@Anooj

You are right, of course. The original version I posted appended word to the StringBuilder before the length was tested. I didn't update the length test at that time. I have now. Thanks.

- somasekhar akiri

thanks mike nice article and nice extension method

- Tara

Thanks for this - just what I needed!

- Jay Tsultim

How would I include this in a cshtml file aka razor

- Mike

@Jay,

Copy the code into a C# class files (ends with .cs) and save it in an App_Code folder.

- Cat

I'm using vb .net. I copied your code into a new class and it works great if I call it with a button from a datalist but when I append <%# Eval("myString").ToString().Chop(50) %> into my html, I get an error 'Chop' is not a member of 'String'. Am I missing something obvious? Ideally, I want the truncation to execute on initialisation of the datalist so that when the user clicks a "More Details" button, I can display the full record. Any advice you can give would be greatly appreciated.

- Darwin

I normally take the code and run. But I have to stop here and say this is an awesome implementation. I was going to trim in the controller and then pass this to the view. But this is a much better approach. I did not know this could be done in this fashion.
Nice work.

- Samuel

I have failed to use the extension because it throws an error that it doesn't recognise the chop method .any suggestions will be of great help..am using asp.net mvc 5 with razor

- Mike

@Samuel,

The best advice I can give you is to post a question to a forum like http://forums.asp.net or http:www.stackoverflow.com, explaining what you have done and what you expected to happen.

Recent Comments

Gayan 7/3/2015 6:20 AM
In response to 7 C# 6.0 Features That Every ASP.NET Developer Should Know About
Great Article thanks...

Semil 7/1/2015 7:03 AM
In response to iTextSharp - Drawing shapes and Graphics
I have created a rectangle using above methode. Now I want to add a text in the center of this How I...

Satyabrata Mohapatra 6/30/2015 6:12 PM
In response to Reading Excel Files Without Saving To Disk In ASP.NET
Ahh.....this is awesome. Happy to see after a long time you wrote a article on web form :D...

Marty 6/30/2015 7:16 AM
In response to Posting Data With jQuery AJAX In ASP.NET Razor Web Pages
Mike, you're the Man! Another great article. So incredibly helpful. I'm definitely going to buy your...

Rohan 6/30/2015 5:32 AM
In response to ASP.NET MVC 5 with EF 6 - Working With Files
Very good and helpful tutorial. Thanks. Just wanted to know what would be the max file size limit we...

Fernando 6/30/2015 1:59 AM
In response to Programmatically accessing data from DataSource controls
What if I want to pass parameters natively using the DataSourceSelectArguments object, instead of be...

pankaj 6/29/2015 3:13 PM
In response to How to retain carriage returns or line breaks in an ASP.NET web page
very nice i'm use this in my code thank you.... ...

Mike 6/29/2015 2:22 AM
In response to MVC 5 with EF 6 in Visual Basic - Sorting, Filtering and Paging
This is the first example that I have found that works....

Marty 6/28/2015 4:57 AM
In response to Posting Data With jQuery AJAX In ASP.NET Razor Web Pages
Mike, what if I don't want to render back the text to the browser, but I want to send it some other...

Mike 6/27/2015 4:00 PM
In response to Migrating Classic ASP To ASP.NET Razor Web Pages Part One- Razor Syntax And Visual Basic
have you used any of the code converters to convert classic asp to c#? If so, which one do you have...