Displaying The First n Characters Of Text

4.64 (14 votes)

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: 33120

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

Ghazanfar 30/01/2016 06:43
In response to Getting Started with ASP.NET MVC 5 using Visual Basic
Nice working. Please keep it up to convert csharp code into vb.net. Its very helpful for vb...

sara 29/01/2016 09:39
In response to Simple Login and Redirect for ASP.NET and Access
Hi there, I am trying to validate and check for inputs entered. When I don't enter any inputs and...

Martin Thatcher 28/01/2016 17:28
In response to MVC 5 with EF 6 in Visual Basic - Advanced Entity Framework Scenarios
A small typo I think. In the code section that begins Function Index(ByVal SelectedDepartment As As...

Suresh_thefame 28/01/2016 08:03
In response to Sessions and Shopping Carts
Helpful....

Andrey Kurdyumov 28/01/2016 05:47
In response to ASP.NET 5: Uploading files with ASP.NET MVC 6
@Lee IFormFile has OpenReadStream(): Stream method...

Alisa 27/01/2016 18:37
In response to A Better Way To Export Gridviews To Excel
Thanks for this example! I am also asking about the date fields having to be re-formatted when the a...

Dan Buckley 27/01/2016 00:47
In response to What ASP.NET Can And Cannot Do
New to all things programming, this was very helpful and clear. Please write more....

satyabrata 26/01/2016 16:16
In response to Request.Form Is Empty When Posting To ASPX Page
Thank you....

david sanchez 26/01/2016 09:51
In response to ASP.NET MVC 5 with EF 6 - Working With Files
Thanks! This line " <img src="~/images/@Model.FilePaths.First(f => f.FileType == alt="" />" an...

Bryon 25/01/2016 15:06
In response to Windows Authentication With ASP.NET Web Pages
Was hoping this would help solve the issues I'm having. Then I saw the dates and new it was too old....