【问题标题】:Helper to generate "friendly URL" in Razor (C#/MVC 4)在 Razor (C#/MVC 4) 中生成“友好 URL”的帮助程序
【发布时间】:2013-06-10 03:22:36
【问题描述】:

目标

在 Razor 中创建将字符串转换为友好字符串的内容(我使用的是 C#/MVC4)

问题

我有以下代码:

<li>
   <img 
    src="~/Images/Products/@Model["CategoryName"]/@Model["ProductThumbnailUrl"]"
   />
</li>

我的类别名称是这样的:CDs, DVDs and Bluray我想像cds-dvds-and-blurays这样使用类似的东西连接为“友好字符串”:

<li>
   <img 
    src="~/Images/Products
          /@HtmlHelper.ConvertToFriendlyString(@Model["CategoryName"])
          /@Model["ProductThumbnailUrl"]"
   />
</li>

你们都明白吗?

那么,有人知道吗?

提前致谢。

【问题讨论】:

标签: c# asp.net-mvc-4 razor


【解决方案1】:

我以前做过。在我挖掘代码时,请注意以下几点:

  1. 确保存储生成的 URL,以便进行冲突检测;将字符串转换为友好的 URL 几乎肯定会造成损失,因此您需要逻辑来解决冲突的名称。
  2. 您应该尝试将变音符号转换为更易于输入的字符。
  3. 考虑使 url 到资源的映射成为 1:many 关系;如果您的资源名称发生更改,您可能希望生成一个新 URL将旧 URL 重定向到新 URL。

更新:这是我的代码。 Stack Overflow 方法还可以,但我更喜欢我的方法;它没有使用一组字符替换,而是使用出色的 .NET Unicode 库来创建更友好的字符:

public static string ConvertToFriendlyUrl(string text)
{
    var decomposed = text.Normalize(NormalizationForm.FormKD);
    var builder = new StringBuilder();
    foreach (var ch in decomposed)
    {
        var charInfo = CharUnicodeInfo.GetUnicodeCategory(ch);
        switch (charInfo)
        {
            // Keep these as they are
            case UnicodeCategory.DecimalDigitNumber:
            case UnicodeCategory.LetterNumber:
            case UnicodeCategory.LowercaseLetter:
            case UnicodeCategory.CurrencySymbol:
            case UnicodeCategory.OtherLetter:
            case UnicodeCategory.OtherNumber:
                builder.Append(ch);
                break;

            // Convert these to dashes
            case UnicodeCategory.DashPunctuation:
            case UnicodeCategory.MathSymbol:
            case UnicodeCategory.ModifierSymbol:
            case UnicodeCategory.OtherPunctuation:
            case UnicodeCategory.OtherSymbol:
            case UnicodeCategory.SpaceSeparator:
                builder.Append('-');
                break;

            // Convert to lower-case
            case UnicodeCategory.TitlecaseLetter:
            case UnicodeCategory.UppercaseLetter:
                builder.Append(char.ToLowerInvariant(ch));
                break;

            // Ignore certain types of characters
            case UnicodeCategory.OpenPunctuation:
            case UnicodeCategory.ClosePunctuation:
            case UnicodeCategory.ConnectorPunctuation:
            case UnicodeCategory.Control:
            case UnicodeCategory.EnclosingMark:
            case UnicodeCategory.FinalQuotePunctuation:
            case UnicodeCategory.Format:
            case UnicodeCategory.InitialQuotePunctuation:
            case UnicodeCategory.LineSeparator:
            case UnicodeCategory.ModifierLetter:
            case UnicodeCategory.NonSpacingMark:
            case UnicodeCategory.OtherNotAssigned:
            case UnicodeCategory.ParagraphSeparator:
            case UnicodeCategory.PrivateUse:
            case UnicodeCategory.SpacingCombiningMark:
            case UnicodeCategory.Surrogate:
                break;
        }
    }

    var built = builder.ToString();
    while (built.Contains("--")) 
        built = built.Replace("--", "-");
    while (built.EndsWith("-"))
    {
        built = built.Substring(0, built.Length - 1);
    }
    while (built.StartsWith("-"))
    {
        built = built.Substring(1, built.Length - 1);
    }
    return built;
}

public static string GetIncrementedUrl(string url)
{
    var parts = url.Split('-');
    var lastPortion = parts.LastOrDefault();
    int numToInc;
    bool incExisting;
    if (lastPortion == null)
    {
        numToInc = 1;
        incExisting = false;
    }
    else
    {
        if (int.TryParse(lastPortion, out numToInc))
        {
            incExisting = true;
        }
        else
        {
            incExisting = false;
            numToInc = 1;
        }
    }

    var fragToKeep = incExisting 
        ? string.Join("-", parts.Take(parts.Length - 1).ToArray()) 
        : url;
    return fragToKeep + "-" + (numToInc + 1).ToString();
}

public static string SeekUrl(
    string name, Func<string, bool> uniquenessCheck)
{
    var urlName = UrlUtils.ConvertToFriendlyUrl(name);
    while (!uniquenessCheck(urlName))
    {
        urlName = UrlUtils.GetIncrementedUrl(urlName);
    }

    return urlName;
}

【讨论】:

  • 关于注意事项:您是对的!关于您的代码:其中有一些逻辑以避免名称冲突?不知道我的理解是否正确。
  • 我曾用它来为多个事物生成 URL,因此名称冲突检查是通用的; Func&lt;string, bool&gt; uniquenessCheck 参数执行名称冲突检查。调用者根据其需要传递其自己的此检查实现。例如,name =&gt; !yourDb.Things.Any(t =&gt; t.Name == name)
  • 哦,好的!知道了!精彩的解释,谢谢!但是,与 Razor Engine 的集成怎么样?你能帮我澄清一下吗?
猜你喜欢
  • 2010-11-29
  • 2010-09-07
  • 2011-03-05
  • 2010-12-31
  • 1970-01-01
  • 2013-09-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多