Dre*_*kes 36 .net razor razor-declarative-helpers asp.net-mvc-3
使用MVC 3 RTM我变得很奇怪NullReferenceException:
@helper TestHelperMethod() {
var extra = "class=\"foo\"";
<div @Html.Raw(extra)></div>
}
Run Code Online (Sandbox Code Playgroud)
事实证明Html(类型HtmlHelper)是null.
我以前从未在常规视图中看过这个.我开始在Razor中尝试声明性辅助方法(到目前为止它们似乎有点受限)并且我对我在这里看到的东西感到非常难过.
kka*_*ara 38
使用Drew Noakes的建议,我已经找到了一个现在可以解决这个问题的解决方法,一旦在更新版本的MVC中解决问题就可以轻松删除(即如果更多的东西没有改变会破坏它:) )
目标是能够在声明性帮助器方法中使用HtmlHelper,该方法位于App_Code中的文件中,而不会出现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; }
}
}
Run Code Online (Sandbox Code Playgroud)
这似乎可以解决问题,因为我现在可以编写以下帮助程序(在同一个文件中):
@helper PrintAsRaw(string htmlString)
{
@Html.Raw(htmlString)
}
Run Code Online (Sandbox Code Playgroud)
显然,辅助方法只是一个例子.这个解决方案的缺点是必须在App_Code中的所有帮助器声明文件中引入@functions声明,但是确实避免了对辅助器的调用复杂化,因为您可以简单地在视图中写入:
@MyAppCodeFile.PrintAsRaw("<p>My paragraph</p>")
Run Code Online (Sandbox Code Playgroud)
希望这可以帮助...
Dar*_*rov 33
@helper TestHelperMethod(HtmlHelper html) {
var extra = "class=\"foo\"";
<div@html.Raw(extra)></div>
}
Run Code Online (Sandbox Code Playgroud)
另一种可能性是将助手编写为扩展方法:
public static class HtmlExtensions
{
public static MvcHtmlString TestHelperMethod(this HtmlHelper)
{
var div = new TagBuilder("div");
div.AddCssClass("foo");
return MvcHtmlString.Create(div.ToString());
}
}
Run Code Online (Sandbox Code Playgroud)
然后:
@Html.TestHelperMethod()
Run Code Online (Sandbox Code Playgroud)
Bri*_*per 23
我知道这不是重点,但是Html.Raw(value)根据System.Web.Mvc.dll的源代码,如果只是你希望在谷歌上找到这个问题时使用(就像我一样)所有的Html.Raw都是:
public IHtmlString Raw(string calue)
{
return new HtmlString(value);
}
Run Code Online (Sandbox Code Playgroud)
所以我刚刚@(new HtmlString(value))在我的助手中使用过,效果很好.
Ott*_*lis 14
只需更换
@Html.Raw(extra)
Run Code Online (Sandbox Code Playgroud)
同
@(new HtmlString(extra))
Run Code Online (Sandbox Code Playgroud)
我想我知道导致问题的原因...
Html属性获取器的定义是:
public static HtmlHelper Html {
get {
WebPage currentWebPage = CurrentPage as WebPage;
if (currentWebPage == null) {
return null;
}
return currentWebPage.Html;
}
}
Run Code Online (Sandbox Code Playgroud)
在我的辅助方法中设置一个断点表明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
Run Code Online (Sandbox Code Playgroud)
请注意,我的视图的基类已在Web.config中指定:
<system.web.webPages.razor>
<pages pageBaseType="My.Site.MyWebViewPage">
...
Run Code Online (Sandbox Code Playgroud)
它以通用和非通用形式定义:
public abstract class MyWebViewPage : WebViewPage { ... }
public abstract class MyWebViewPage<TModel> : WebViewPage<TModel> { ... }
Run Code Online (Sandbox Code Playgroud)
因此,如果其他人没有发生此问题,则可能他们没有使用custom 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;
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
11703 次 |
| 最近记录: |