Я использую asp.net/C#, и я ищу создать уникальный (?) uris для небольшой CMS-системы, которую создаю.
Я создаю сегмент uri из названия моей статьи, так, например, если название "Моя удивительная статья", uri будет www.website.com/news/my-amazing-article
Есть две части. Во-первых, какие персонажи, по-твоему, мне нужно разбить? Я заменяю пробелы "-", и я думаю, что я должен также лишить символ "/". Можете ли вы подумать о том, что может вызвать проблемы? "?" возможно? Должен ли я удалять все не-альфа-символы?
Второй вопрос, выше, я упомянул, что урис МОЖЕТ быть уникальным. Я собирался проверить список uri перед добавлением, чтобы обеспечить уникальность, однако я вижу, что переполнение стека использует число плюс uri. Это, я предполагаю, позволяет дублировать названия? Считаете ли вы, что это будет лучше?
Преобразуйте все диакритики в их базовый символ, а затем разделите все, что не является буквой или цифрой, используя Char.IsLetterOrDigit
.
Затем замените все пробелы на одну тире.
Это то, что мы используем в нашем программном обеспечении.
/// <summary>
/// Convert a name into a string that can be appended to a Uri.
/// </summary>
private static string EscapeName(string name)
{
if (!string.IsNullOrEmpty(name))
{
name = NormalizeString(name);
// Replaces all non-alphanumeric character by a space
StringBuilder builder = new StringBuilder();
for (int i = 0; i < name.Length; i++)
{
builder.Append(char.IsLetterOrDigit(name[i]) ? name[i] : ' ');
}
name = builder.ToString();
// Replace multiple spaces into a single dash
name = Regex.Replace(name, @"[ ]{1,}", @"-", RegexOptions.None);
}
return name;
}
/// <summary>
/// Strips the value from any non english character by replacing thoses with their english equivalent.
/// </summary>
/// <param name="value">The string to normalize.</param>
/// <returns>A string where all characters are part of the basic english ANSI encoding.</returns>
/// <seealso cref="http://stackoverflow.com/questions/249087/how-do-i-remove-diacritics-accents-from-a-string-in-net"/>
private static string NormalizeString(string value)
{
string normalizedFormD = value.Normalize(NormalizationForm.FormD);
StringBuilder builder = new StringBuilder();
for (int i = 0; i < normalizedFormD.Length; i++)
{
UnicodeCategory uc = CharUnicodeInfo.GetUnicodeCategory(normalizedFormD[i]);
if (uc != UnicodeCategory.NonSpacingMark)
{
builder.Append(normalizedFormD[i]);
}
}
return builder.ToString().Normalize(NormalizationForm.FormC);
}
Что касается использования сгенерированного имени в качестве уникального идентификатора, я бы поругался. Используйте сгенерированное имя как помощник SEO, но не как ключевой распознаватель. Если вы посмотрите, как stackoverflow ссылается на свои страницы:
http://stackoverflow.com/questions/249087/how-do-i-remove-diacritics-accents-from-a-string-in-net
^--ID ^--Unneeded name but helpful for bookmarks and SEO
Здесь вы можете найти идентификатор. Эти два URL указывают на одну и ту же страницу:
http://stackoverflow.com/questions/249087/how-do-i-remove-diacritics-accents-from-a-string-in-net
http://stackoverflow.com/questions/249087/
Вы хотите проконсультироваться с IETF RFC 3986, в котором описываются URI и что является законным, а не законным.
Помимо действительности, возможно, вам нужен читаемый URI. В этом случае удалите все не буквенно-цифровые символы.
В stackoverflow заголовок может меняться, поэтому использование идентификатора для уникального, но неизменного отличителя для URI. Если у вас нет сменных заголовков, вы должны быть в порядке, просто используя текст. Если вы можете редактировать заголовки после публикации, тогда идентификатор может быть предпочтительным.
Для вопроса 1: Rob Conery имеет довольно полезное решение на основе Regex для очистки строк для генерации slug. Здесь метод расширения (просто добавьте это в статический класс):
public static string CreateSlug(this string source)
{
var regex = new Regex(@"([^a-z0-9\-]?)");
var slug = "";
if (!string.IsNullOrEmpty(source))
{
slug = source.Trim().ToLower();
slug = slug.Replace(' ', '-');
slug = slug.Replace("---", "-");
slug = slug.Replace("--", "-");
if (regex != null)
slug = regex.Replace(slug, "");
if (slug.Length * 2 < source.Length)
return "";
if (slug.Length > 100)
slug = slug.Substring(0, 100);
}
return slug;
}
Для вопроса 2 вы можете просто установить ограничение UNIQUE для столбца в базе данных, если хотите, чтобы они были уникальными. Это позволит вам обмануть исключение и предоставить полезный пользовательский ввод. Если вам это не нравится, то полагаться на почтовый идентификатор, вероятно, является хорошей альтернативой.