如何使用MVC Html Helpers截断字符串?

8

我正在尝试截断一个长字符串,只在我的首页上显示。它的显示方式如下:

<td>
    @Html.DisplayFor(modelItem => item.Description)
</td>

描述可以长达500个字符,但在那个网格布局上我无法展示那么多。我希望只显示前25个字符,因为他们可以在详细页面上看到全部内容,但似乎无法在模型层面上截断它。

像这样的方式会很好:

@Html.DisplayFor(modelItem => item.Description.Take(25))
@Html.DisplayFor(modelItem => item.Description.Substring(0,25)

编辑

当我尝试使用任一方法时,在运行时我会遇到以下异常。

Templates can be used only with field access, property access, single-dimension array index, or single-parameter custom indexer expressions.

你是否考虑创建一个额外的模型属性来执行子字符串操作并使用它? - Mike Cheel
是的,如果没有办法使用模板和单个属性进行操作,那就是我要这样做的方式。 - Refracted Paladin
你在这里遇到的具体问题是传递给 Html.DisplayFor 的表达式必须引用实际属性,而不是特定值。换句话说,你只能使用 @Html.DisplayFor(m => item.Description),而不能使用 @Html.DisplayFor(m => item.Description.Substring(0, 25))。但是,你不需要为此使用 Html.DisplayFor,所以你可以直接写 @item.Description.Substring(0, 25)。然而,请记住 @48klocs 对 Nathan A 的回答的评论。 - Chris Pratt
1
请注意,Take() 返回的是 IEnumerable<char>,而不是字符串。Substring() 更适合这种情况。 - Nathan A
7个回答

28

不要使用html助手程序,只需执行以下操作:

@item.Description.Substring(0, Math.Min(item.Description.Length, 25));

我假设你正在某个循环中,其中item是当前元素。


2
如果字符串长度不超过25个字符,那么会抛出一个“ArgumentOutOfRangeException”异常。 - 48klocs
@NathanA,这个很好用,但是你能提供第二个选项来显示末尾的点吗,就像这样 mydescription .....,我试过这个,但在解析时出现错误,你有什么想法吗? - Shaiju T
@NathanA 非常感谢你。我已经为这个问题苦苦挣扎了2个小时,终于找到了解决办法。 - Sumedha Vangury

7
你可以使用扩展方法来实现这一点。
public static string Truncate(this string source, int length)
{
    if (source.Length > length)
    {
        source = source.Substring(0, length);
    }

    return source;
}

那么在您看来:

@item.Description.Truncate(25)

那仍然不会起作用。DisplayFor只接受产生值的表达式(特别是错误中列出的内容),而不是方法调用。这就是生成Templates错误的原因。 - Nathan A
@NathanA 你可能是对的。我没有检查 DisplayForDisplay 的调用有什么区别。我认为一个命名为 Display 的元素应该可以工作,但我只是猜测。 - 48klocs
看起来更好了。是一个很好的通用应用程序。 - Nathan A

4
你可以在数据传递到视图之前将其截断,或者使用以下Razor代码:

你可以在数据传递到视图之前将其截断,或者使用以下Razor代码:

@{
    var shortDescript = String.Concat(modelItem.Take(25));
}
@Html.DisplayFor(modelItem => shortDescript)

虽然这样可能行得通,但你为什么要使用DisplayFor呢?如果你在数据模型的成员上使用它,那么它所带来的任何好处都会因为以这种方式使用而丧失。 - Nathan A
假设类型没有改变(从字符串到字符串),您仍然可以使用相同的显示模板。请参见https://dev59.com/0Ww15IYBdhLWcg3w1vSB#6365658。 - arserbin3

1
你可以考虑为这种情况创建一个特殊的模型属性:

public class MyModel
{
    public string MyDescription {get; set;}
    public string MyShortDescription {
        get 
        {
              return Truncate(MyDescription, 25);
        }
}

private string Truncate(string, howMany)
{
   // Code to perform the substring here
}

@Html.DisplayFor(modelItem => item.MyShortDescription);

1

如果您想使用HTML助手,请尝试此方法。比如说,您想要获取第一个空格之前的字符串部分(.IndexOf(' '))(或者您可以直接使用预定义的索引25,就像您所说的那样):

@Html.DisplayFor(modelItem => item.Description).ToString().Substring(0,item.Description.IndexOf(' '))

1

ASP Net Core 3 MVC 的 HTML 辅助程序。

public static HtmlString Truncate(this IHtmlHelper helper, string text, int maxLength = 100)
{
    if (text == null) return new HtmlString("");

    if (text.Length > maxLength)
    {
        text = text.Substring(0, maxLength) + "...";
    }
    return new HtmlString($"{text}");
}

在cshtml文件中使用。
@Html.Truncate(item.Description)

或者您可以使用param

@Html.Truncate(item.MusicUrl, 50)

0

尝试使用扩展

public static string TruncateMiddle(this string value, int lengthExpected, string separator = "...")
    {
        if (value.Length <= lengthExpected) return value;

        decimal sepLen = separator.Length;
        decimal charsToShow = lengthExpected - sepLen;
        decimal frontChars = Math.Ceiling(charsToShow / 2);
        decimal backChars = Math.Floor(charsToShow / 2);

        return value.Substring(0, (int)frontChars) + separator + value.Substring(value.Length - (int)backChars);            
    }

使用

MyLongString.TruncateMiddle(50)

返回类似于这样的内容:Lorem ipsum dolor sit ame...onsectetur cras amet。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接