I have the following C# code:
ArticleContent = ds1.Tables[0].Rows[i]["ArticleContent"].ToString();
if (ArticleContent.Length > 260)
{
ArticleContent = ArticleContent.Remove(ArticleContent.IndexOf('.', 250)) + "...";
}
The problem here is that I get this error message:
StartIndex cannot be less than zero.
Why and how can I fix it?
7 Answers
You are getting that error because there is no '.' character on or after index 250, so IndexOf returns -1. You then try to remove the character at position -1 which gives you the error you are seeing.
Also realize that Remove only removes one character at that position, not everything after that position. What I suspect you want is:
if (ArticleContent.Length > 260)
{
int lastPeriod = ArticleContent.LastIndexOf('.');
if(lastPeriod < 0)
lastPeriod = 257; // just replace the last three characters
ArticleContent = ArticleContent.Substring(0,lastPeriod) + "...";
}
That will add ellipses to the string, making sure it is no longer that 260 characters and breaking at a sentence if possible.
It's clear why it's failing, but what exactly are you trying to do? If it's simply to truncate a string to a particular length and indicating the truncation, I might suggest the extension method listed below. It's usage is simply:
ArticleContent = ArticleContent.Truncate(250);
Truncate extension method:
public static string Truncate(this string pThis, int pLength)
{
if (string.IsNullOrEmpty(pThis))
return pThis;
if (0 >= pLength)
return string.Empty;
var lTruncatedString = pThis;
const string lEllipses = @"…";
if (pThis.Length > pLength)
{
var lSubstringLength = Math.Max(pLength - lEllipses.Length, 0);
lTruncatedString = pThis.Substring(0, lSubstringLength) + lEllipses;
if (lTruncatedString.Length > pLength)
lTruncatedString = lTruncatedString.Substring(0, pLength);
}
return lTruncatedString;
}
I hope this helps.
If the below can't find the '.' it will return -1 which will not be valid for the RemoveAt
ArticleContent.IndexOf('.', 250)
As others wrote - when your ArticleContent has no '.' character - method .Remove() will return -1.
I suggest to add one more condition in your if:
if (ArticleContent.Length > 260 && ArticleContent.Contains('.'))
{
ArticleContent = ArticleContent.Remove(ArticleContent.IndexOf('.', 250)) + "...";
}
Source of error: '.' does not appear after index 250. The IndexOf method returns -1 in this case.
While others have just identified the source of the error, I will also post a fix to your problem.
Solution: Use the LastIndexOf method:
if (ArticleContent.Length > 260)
{
if (ArticleContent.Remove(ArticleContent.LastIndexOf('.') != -1)
{
ArticleContent = String.Concat(ArticleContent.Remove(ArticleContent.LastIndexOf('.')), "...");
}
else
{
ArticleContent = String.Concat(ArticleContent.Substring(0, 257), "...")
}
}
There's a chance that there is no . after position 250. You need to check first:
ArticleContent = ds1.Tables[0].Rows[i]["ArticleContent"].ToString();
var periodPosition = ArticleContent.IndexOf('.', 250);
if (ArticleContent.Length > 260 && periodPosition >= 0)
{
ArticleContent = ArticleContent.Remove(ArticleContent.IndexOf('.', 250)) + "...";
}
ArticleContent = ds1.Tables[0].Rows[i]["ArticleContent"].ToString();
if (ArticleContent.Length > 260)
{
if (ArticleContent.Substring(250).Contains("."))
{
ArticleContent = ArticleContent.Remove(ArticleContent.IndexOf('.', 250)) + "...";
}
else
{
ArticleContent = ArticleContent.Remove(ArticleContent.Substring(0, 250)) + "...";
}
}