13

I have the following inside of my view

     @Html.DisplayFor(modelItem => item.FirstName)

I need to get the first initial of the First Name.

I tried

    @Html.DisplayFor(modelItem => item.FirstName).Substring(1,1) 

but it does not seem to work. I get the following error: .. 'System.Web.Mvc.MvcHtmlString' does not contain a definition for 'Substring' and no extension

1
  • I'd be really surprised if you wanted Substring(1,1) instead of Substring(0,1).
    – tvanfosson
    Commented Feb 22, 2012 at 16:01

8 Answers 8

31

You could implement in view as follows:

@Html.DisplayFor(modelItem => modelItem.FirstName).ToString().Substring(0,5)
2
  • Wouldn't that display a substring the namespace and type of FirstName? Commented Apr 14, 2020 at 11:25
  • 2
    This can break. DisplayFor() for a string by default returns an HtmlString, with the HTML-encoded string, but can also trigger a display template to be rendered, not all strings are rendered as plain strings. If the template returns more than the string, for example <span class="fancy-string">@Model</span>", or if the input string contains HTML entities ("foo&amp;bar"), you now have partial HTML being printed. Using a separate model property that returns a substring is the way to go.
    – CodeCaster
    Commented Nov 19, 2020 at 8:00
9

Might I suggest that the view is not the right place to do this. You should probably have a separate model property, FirstInitial, that contains the logic. Your view should simply display this.

  public class Person
  {
       public string FirstName { get; set; }

       public string FirstInitial
       {
           get { return FirstName != null ? FirstName.Substring(0,1) : ""; }
       }

       ...
   }


   @Html.DisplayFor( modelItem => modelItem.FirstInitial )
7

You should put a property on your ViewModel for that instead of trying to get it in the view code. The views only responsibility is to display what is given to it by the model, it shouldn't be creating new data from the model.

3

You can use a custom extension method as shown below:

/// <summary>
/// Returns only the first n characters of a String.
/// </summary>
/// <param name="str"></param>
/// <param name="start"></param>
/// <param name="maxLength"></param>
/// <returns></returns>
public static string TruncateString(this string str, int start, int maxLength)
{        
    return str.Substring(start, Math.Min(str.Length, maxLength));
}
1

This worked for me (no helper):

@item.Description.ToString().Substring(0, (item.Description.Length > 10) ? 10 : item.Description.Length )
1

This will truncate at 10 characters and add "..." to the end if it is longer than 13 characters.

@if (item.Notes.Length <= 13)
{
  @Html.DisplayFor(modelItem => item.FirstName)
}
else
{
  @(item.FirstName.ToString().Substring(0, 10) + "...")
}
0

Two things I learned while trying to solve this problem which are key:

  1. Razor allows C# which means the .Substring(0,1) method will work
  2. (WHERE I WENT WRONG) - Be very careful that none of your item.FirstNames are empty or contain fewer characters than being requested as the string length.

My solution was the following:

string test = item.FirstName.ToString();
    string test_add = ""; //creating an empty variable
    if(test.Length == 0) //situation where we have an empty instance
    {
        test_add = "0"; //or whatever you'd like it to be when item.FirstName is empty
    }
    else
    {
        test_add = test.Substring(0, 1);
    }

and you can use @test_add in your razor code in place of @item.FirstName

-17

If you are only wanting to display the first character of item.FirstName why not do:

@Html.DisplayFor(modelItem => item.FirstName.Substring(1,1))

You have it the wrong side of the closing bracket.

1
  • 5
    This won't work. You will get an InvalidOperationException because method calls are not supported in lambda expressions used by html helpers. Commented Feb 22, 2012 at 16:21

Not the answer you're looking for? Browse other questions tagged or ask your own question.