40

使用 MVC 3 RTM 我很奇怪NullReferenceException

@helper TestHelperMethod() {
    var extra = "class=\"foo\"";
    <div @Html.Raw(extra)></div>
}

原来Html(类型HtmlHelper)是null

我以前从未在常规视图中看到过这种情况。我开始在 Razor 中试验声明性辅助方法(到目前为止,它们似乎有点有限),我对我在这里看到的内容感到非常困惑。

4

6 回答 6

41

使用Drew Noakes 的建议,我已经找到了一种解决方法,它现在可以解决问题,一旦问题在较新版本的 MVC 中得到解决,就可以很容易地删除它(也就是说,如果没有改变更多的东西会破坏它:) )

目标是能够在 App_Code 中的文件中的声明性帮助方法中使用 HtmlHelper,而不会出现 NullReferenceException。为了解决这个问题,我在 App_Code 的所有文件中包含以下内容:

@using System.Web.Mvc;

@functions
{
    private static new HtmlHelper<object> Html
    {
        get { return ((WebViewPage)CurrentPage).Html; }
    }

    private static UrlHelper Url
    {
        get { return ((WebViewPage)CurrentPage).Url; }
    }
}

这似乎确实起到了作用,因为我现在可以编写以下帮助程序(在同一个文件中):

@helper PrintAsRaw(string htmlString)
{
     @Html.Raw(htmlString)
}

显然,辅助方法只是一个例子。该解决方案的缺点是必须在 App_Code 的所有帮助程序声明文件中引入 @functions 声明,但确实避免了对帮助程序的调用复杂化,因为您可以简单地在视图中编写:

@MyAppCodeFile.PrintAsRaw("<p>My paragraph</p>")

希望这可以帮助...

于 2011-08-11T11:00:52.767 回答
35

这是那些 helpers 的已知限制。一种可能性是将其作为参数传递:

@helper TestHelperMethod(HtmlHelper html) {
    var extra = "class=\"foo\"";
    <div@html.Raw(extra)></div>
}

另一种可能性是将助手编写为扩展方法:

public static class HtmlExtensions
{
    public static MvcHtmlString TestHelperMethod(this HtmlHelper)
    {
        var div = new TagBuilder("div");
        div.AddCssClass("foo");
        return MvcHtmlString.Create(div.ToString());
    }
}

进而:

@Html.TestHelperMethod()
于 2011-03-12T14:58:52.393 回答
25

我知道这不是重点,但如果只是Html.Raw(value)您希望根据 System.Web.Mvc.dll 的源代码在 Google(就像我一样)上找到这个问题时使用,那么 Html.Raw 所做的就是:

public IHtmlString Raw(string calue)
{
    return new HtmlString(value);
}

所以我刚刚使用@(new HtmlString(value))了我的助手,它工作得很好。

于 2012-04-30T10:13:51.447 回答
15

只需更换

 @Html.Raw(extra)

@(new HtmlString(extra))
于 2013-04-24T13:37:29.753 回答
5

我想我知道是什么导致了这个问题......

Html属性 getter的定义是:

public static HtmlHelper Html {
    get { 
        WebPage currentWebPage = CurrentPage as WebPage;
        if (currentWebPage == null) {
            return null;
        } 
        return currentWebPage.Html;
    } 
} 

在我的辅助方法中设置断点表明它CurrentPage实际上不是 的实例WebPage,因此是null值。

这是CurrentPage(我的类名略有修改)的类型层次结构:

ASP._Page_Views_mycontroller_View_cshtml
  My.Site.MyWebViewPage`1
    System.Web.Mvc.WebViewPage`1
      System.Web.Mvc.WebViewPage
        System.Web.WebPages.WebPageBase
          System.Web.WebPages.WebPageRenderingBase
            System.Web.WebPages.WebPageExecutingBase
              System.Object

请注意,我的视图的基类已在 Web.config 中指定:

<system.web.webPages.razor>
  <pages pageBaseType="My.Site.MyWebViewPage">
    ...

它以通用和非通用形式定义:

public abstract class MyWebViewPage : WebViewPage { ... }
public abstract class MyWebViewPage<TModel> : WebViewPage<TModel> { ... }

所以,如果其他人没有出现这个问题,也许他们没有使用自定义pageBaseType.

另请注意,我已将@helper声明放入其中,App_Code\Helpers.cshtml以期使其全球可访问。

我做错了什么,还是这是一个错误?

编辑感谢达林指出这是一个已知问题。不过,为什么不将Html属性重新定义为:

public static HtmlHelper Html {
    get { 
        WebPage currentWebPage = CurrentPage as WebPage;
        if (currentWebPage != null) {
            return currentWebPage.Html;
        } 
        WebViewPage currentWebViewPage = CurrentPage as WebViewPage;
        if (currentWebViewPage != null) {
            return currentWebViewPage.Html;
        } 
        return null;
    } 
} 
于 2011-03-12T13:18:05.417 回答
1

我遇到了同样的问题,这行代码成功了。这不是使用 HtmlHelper 的解决方案,它只是在声明性剃刀助手中编写 RAW html 的一种方式。

@{CurrentPage.WriteLiteral("html code");}
于 2012-03-06T11:57:10.917 回答