MVC Razor:Helper方法,用于在空时呈现备用内容

时间:2013-03-01 14:57:59

标签: asp.net-mvc razor

我有一些数据,有时数据是空白的。我不是在我的视图中制作一堆疯狂的逻辑,而是使用一个帮助方法来呈现数据(如果它存在),并在字符串为空/ null时呈现一些只是说“N / A”的HTML。

理想语法:@Helpers.RenderThisOrThat(Model.CustomerPhone)

如果Model.CustomerPhone(字符串)为空,则会改为呈现此备用HTML:<span class='muted'>N/A</span>

这是我们到目前为止所拥有的:

@helper RenderThisOrThat(string stringToRender, string methodToGetAlternateText = null)
{
    @RenderThisOrThat(MvcHtmlString.Create(stringToRender), methodToGetAlternateText)
}

@helper RenderThisOrThat(MvcHtmlString stringToRender, string methodToGetAlternateText = null)
{
    if (string.IsNullOrWhiteSpace(stringToRender.ToHtmlString()))
    {
        if (!string.IsNullOrWhiteSpace(methodToGetAlternateText)) {
            @methodToGetAlternateText
        }

        <span class='muted'>N/A</span>
    }

    @stringToRender
}

这个工作正常,直到我们想要将除字符串之外的内容传递给任一参数。例如,当我们有一个电子邮件地址时,我们希望它是该电子邮件的链接,而不仅仅是电子邮件的字符串。

@Helpers.RenderThisOrThat(@<a href="mailto:@Html.DisplayFor(m => m.CustomerEmail)">@Html.DisplayFor(m => m.CustomerEmail)</a>)

它给我们错误:“无法将lambda表达式转换为'string'类型,因为它不是委托类型”

我们对如何完成这项工作感到茫然......在这里有任何帮助吗?

2 个答案:

答案 0 :(得分:2)

你正在寻找一个带字符串的助手:

  1. 如果字符串不为空,则渲染该字符串。
  2. 如果字符串不为空,则渲染给定模板。
  3. 如果字符串为空,则渲染“N / A”html。
  4. 如果字符串为空,则呈现给定模板。
  5. 当将剃刀块作为参数传递给函数时,razor将块打包为Func。更改辅助函数中的参数以获取该类型的委托,并且不要忘记调用这些委托(我选择传递null)。

    这些助手应该处理这些情况。

    <强>解决方案

    @helper RenderThisOrThat(string stringToRender, Func<object, IHtmlString> leftTemplate = null, Func<object, IHtmlString> rightTemplate = null)
    {
        var shouldRenderLeft = !string.IsNullOrWhiteSpace(stringToRender);
        leftTemplate = leftTemplate ?? (o => MvcHtmlString.Create(stringToRender));
        @RenderThisOrThat(shouldRenderLeft, leftTemplate, rightTemplate)
    }
    
    @helper RenderThisOrThat(bool shouldRenderLeft, Func<object, IHtmlString> leftTemplate, Func<object, IHtmlString> rightTemplate = null)
    {
        var shouldRenderRight = !shouldRenderLeft;
        if (shouldRenderRight)
        {
            if (rightTemplate != null)
            {
                @rightTemplate(null)
            }
            else
            {
                <span class='muted'>N/A</span>
            }
        }
        else
        {
            @leftTemplate(null)
        }
    }
    

    <强>实施例

    1. @Helpers.RenderThisOrThat(Model.StringWithBob)
    2. @Helpers.RenderThisOrThat(Model.StringWithNull)
    3. @Helpers.RenderThisOrThat(Model.StringWithBob, @<span>I'm @Model.StringWithBob</span>)
    4. @Helpers.RenderThisOrThat(Model.StringWithNull, @<span>I'm @Model.StringWithBob</span>)
    5. @Helpers.RenderThisOrThat(Model.StringWithBob, @<span>I'm @Model.StringWithBob</span>, @<span>What about Bob?</span>)
    6. @Helpers.RenderThisOrThat(Model.StringWithNull, @<span>I'm @Model.StringWithBob</span>, @<span>What about Bob?</span>)
    

    将输出:

    1. Bob
    2. <span class='muted'>N/A</span>
    3. <span>I'm Bob</span>
    4. <span class='muted'>N/A</span>
    5. <span>I'm Bob</span>
    6. <span>What about Bob?</span>

答案 1 :(得分:2)

对于一个简单的问题,这是一个非常复杂的解决方案。您不需要创建复杂的视图,事实上,您应该使用Editor / DisplayTemplate,然后将逻辑放在模板中并完成一次,而不需要额外包含辅助函数或其他任何内容。

您还可以在这里更进一步,因为在这种情况下,您正在呈现电子邮件地址。您将DataType属性应用于模型,然后指定电话号码呈现类型。

public class MyModel {
    [DataType(DataType.PhoneNumber)]
    public string PhoneNumber {get;set;}
}

然后在〜/ Views / Shared中创建一个名为DisplayTemplates的文件夹,并在该文件夹中创建一个名为PhoneNumber.cshtml的文件,在其中执行以下操作:

@model string

@if (string.IsEmptyOrWhiteSpace(Model)) {
    @:<span class='muted'>N/A</span>
} else {
   @: <span>@Model</span>
}

然后,在您看来:

@Html.DisplayFor(x => x.PhoneNumber)

就是这样,你的视图中没有复杂的逻辑,到处都没有被污染的帮助函数。这很简单,易于维护。您可以对电子邮件地址执行相同操作,因为还有EmailAddress数据类型。

MVC内置了许多非常好的功能,大多数人根本不使用,因为他们没有花时间学习它。