【问题标题】:Integer extension in mvc razor viewmvc razor 视图中的整数扩展
【发布时间】:2012-02-15 20:47:15
【问题描述】:

我是 ASP.NET MVC 和扩展方法的新手。

我创建了两个想要在视图中使用的扩展:

public static class Extensions
{
    public static string ToYesNo(this bool value)
    {
        return value ? "Yes" : "No";
    }

    public static string MonthToString(this int value)
    {
        return (value >= 1 && value <= 12) ? CultureInfo.CurrentCulture.DateTimeFormat.GetMonthName(value) : "";
    }
}

我可以在视图中将 ToYesNo 与布尔值一起使用,但我无法使用整数查看 MonthToString。我明白了:

'int' does not contain a definition for 'MonthToString'

扩展位于名为 BitvaerkAdmin.Models 的命名空间中,我在 cshtml 文件中引用了它。

为什么我不能使用我的整数扩展?

编辑:

我在我的视图中引用扩展是这样的:

@using BitvaerkAdmin.Models


<h3>
    @ViewBag.Month.MonthToString()
</h3>



@foreach (Order order in ViewBag.Orders)
{
    <td>
    @order.Valid.ToYesNo()
    </td>
}

【问题讨论】:

  • 您能告诉我们您是如何尝试在视图中调用扩展方法的吗?
  • 你确实重新编译了项目,对吧? :)
  • @alexn,这是一个很好的观点。我认为您成功了 :-) 这是我现在能想到的唯一可能的解释,而且是有道理的。 +1。
  • 我添加了一行关于命名空间的内容。但由于 bool 扩展有效,这似乎不是问题。
  • 好的,你现在可以给我们看一下调用代码吗?请在 Razor 视图中使用布尔值和整数。这一切都有些奇怪,因为它应该起作用。我怀疑你没有显示一些重要的细节。您能否提供一个完整的示例,以便我们重现您的问题?

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


【解决方案1】:

好的,既然你已经展示了你的代码,那么它为什么不起作用就很清楚了。您使用ViewBagASP.NET MVC 中万恶之源,以及人们遇到的所有问题的根源 - 此答案的作者几乎没有添加)。

一旦你借用它的路径,坠入深渊是显而易见的。为了让它发挥作用,你需要执行的演员阵容将加速这个秋天:

@((int)(ViewBag.Month).MonthToString())

只需尝试运行以下控制台应用程序,您就会明白动态变量不能用于调度扩展方法:

public static class Extensions
{
    public static string MonthToString(this int value)
    {
        return (value >= 1 && value <= 12) ? CultureInfo.CurrentCulture.DateTimeFormat.GetMonthName(value) : "";
    }
}

class Program
{
    static void Main()
    {
        dynamic foo = 123;
        Console.WriteLine(foo.MonthToString()); // crash at runtime
    }
}

知道为什么当我看到有人使用 ViewBag 时,我总是批评它?因为它会把你引向各种奇怪的事情。你失去了智能感知,你不能在动态变量上调度扩展方法,......

所以实际上你不需要投射。您根本不应该使用任何 ViewBag/ViewData。您应该使用强类型视图模型:

@using BitvaerkAdmin.Models
@model MyViewModel

<h3>
    @Model.Month.MonthToString()
</h3>

@foreach (Order order in Model.Orders)
{
    <td>
        @order.Valid.ToYesNo()
    </td>
}

为了避免 foreach 循环,您可以使用显示模板:

@using BitvaerkAdmin.Models
@model MyViewModel

<h3>
    @Model.Month.MonthToString()
</h3>

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

然后为订单定义一个显示模板,该模板将由框架自动为集合的所有元素呈现 (~/Views/Shared/DisplayTemplates/Order.cshtml):

@using BitvaerkAdmin.Models
@model Order
<td>
    @Model.Valid.ToYesNo()
</td>

现在一切都是强类型的并且可以正常工作。

【讨论】:

    【解决方案2】:

    在我的观点中给出了扩展类的参考后,我尝试了如下方法,它对我有用。

        @using NameSpace Of your Extentions class;
        @{
          int i = 10;          
        }
        <span>@i.MonthToString()</span>
    

    【讨论】:

    • 好的,如果我做同样的事情,它对我有用,但是,当在我的 ViewBag 中的 int 上使用扩展时,我得到了异常?
    • Viewbag 的属性是动态的,因此您必须先将它们转换为 int,然后才能调用您的扩展。
    猜你喜欢
    • 2016-03-22
    • 2011-06-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-01
    相关资源
    最近更新 更多