【问题标题】:Razor helper method not working after upgrade from MVC 3 to 4从 MVC 3 升级到 4 后 Razor 辅助方法不起作用
【发布时间】:2012-05-16 16:54:29
【问题描述】:

我在 App_Code 目录下的文件中有一个辅助方法。该方法在 MVC 3 中运行良好,但在升级到 MVC 4 后就不行了。它在第一个 @if() 块中失败了......

[编辑] 这看起来像是 Razor 引擎中的解析错误。当我的所有对象及其属性都不为空时,我收到“对象引用未设置为对象的实例”错误。我想我得直接去微软了。

[编辑] 错误消息是旧的“对象引用未设置为对象的实例”。这很奇怪,因为条件中的每个对象 AND 属性都是有效的且不为空。

@helper RenderConnectButton(System.Web.Mvc.HtmlHelper helper, ContactTwitterHandleDto contactTwitterHandle, ContactFacebookAccountDto contactFacebookAccount) {
    <ul class="socialMedia inlineList">           
        @if (contactTwitterHandle != null && contactTwitterHandle.IsValid.HasValue && contactTwitterHandle.IsValid.Value)
        {
            var tHandle = "@" + contactTwitterHandle.Handle;
            <li class="twitter">
                <a class="btn" href="http://www.twitter.com/@contactTwitterHandle.Handle" target="_blank">
                    <i></i>
                    <span class="label">@tHandle</span> 
                </a>
                @if(contactTwitterHandle.FollowerCount.HasValue)
                {
                    <div class="count" id="c">
                        <i></i>
                        <u></u>
                        <span class="followers" title="@contactTwitterHandle.FollowerCount.Value followers">@FollowerCount(contactTwitterHandle.FollowerCount.Value)</span>
                    </div>
                }                    
            </li>
            <script type="text/javascript">
                $("#twitter").click(function () {
                    window.location.href = '@(helper.BuildUrlFromExpression<TenantController>(t => t.LinkTwitterAccount()))';
                })
            </script>
        }

        @if (contactFacebookAccount != null && contactFacebookAccount.IsValid.HasValue && contactFacebookAccount.IsValid.Value)
        {
            <li class="facebook">
                <a class="btn" href="@contactFacebookAccount.Url" target="_blank">
                    <i></i>
                    <span class="label">@contactFacebookAccount.Name</span> 
                </a>
                @if(contactFacebookAccount.FriendCount.HasValue)
                {
                    <div class="count" id="c">
                        <i></i>
                        <u></u>
                        <span class="followers" title="@contactFacebookAccount.FriendCount.Value friends">@FriendCount(contactFacebookAccount.FriendCount.Value)</span>
                    </div>
                }
            </li>                
        }
    </ul> }

[更新] 我稍微更改了代码,现在它甚至更奇怪了。我在这一行遇到了与上面相同的错误:

var tLink = "http://www.twitter.com/" + contactTwitterHandle.Handle; 

contactTwitterHandle 和 contactTwitterHandle.Handle 都不为空。

@helper RenderConnectButton(System.Web.Mvc.HtmlHelper helper, ContactTwitterHandleDto contactTwitterHandle, ContactFacebookAccountDto contactFacebookAccount) {
    <ul class="socialMedia inlineList">           
        @if (contactTwitterHandle != null && contactTwitterHandle.IsValid.HasValue && contactTwitterHandle.IsValid.Value)
        {
            var tHandle = "@" + contactTwitterHandle.Handle;
            var tLink = "http://www.twitter.com/" + contactTwitterHandle.Handle;
            <li class="twitter">
                <a class="btn" href="@tLink" target="_blank">
                    <i></i>
                    <span class="label">@tHandle</span> 
                </a>
                @if(contactTwitterHandle.FollowerCount.HasValue)
                {
                    <div class="count" id="c">
                        <i></i>
                        <u></u>
                        <span class="followers" title="@contactTwitterHandle.FollowerCount.Value followers">@FollowerCount(contactTwitterHandle.FollowerCount.Value)</span>
                    </div>
                }                    
            </li>
            <script type="text/javascript">
                $("#twitter").click(function () {
                    window.location.href = '@(helper.BuildUrlFromExpression<TenantController>(t => t.LinkTwitterAccount()))';
                })
            </script>
        }

        @if (contactFacebookAccount != null && contactFacebookAccount.IsValid.HasValue && contactFacebookAccount.IsValid.Value)
        {
            <li class="facebook">
                <a class="btn" href="@contactFacebookAccount.Url" target="_blank">
                    <i></i>
                    <span class="label">@contactFacebookAccount.Name</span> 
                </a>
                @if(contactFacebookAccount.FriendCount.HasValue)
                {
                    <div class="count" id="c">
                        <i></i>
                        <u></u>
                        <span class="followers" title="@contactFacebookAccount.FriendCount.Value friends">@FriendCount(contactFacebookAccount.FriendCount.Value)</span>
                    </div>
                }
            </li>                
        }
    </ul>
}

【问题讨论】:

  • 大概它“失败”并显示错误消息?这是什么?
  • 这可能会有所帮助。我会把它放在上面的问题中。
  • 那么,contactTwitterHandle 似乎极有可能为空。启动调试器并找出原因。
  • 我一直在调试。它不为空,因此这篇文章。
  • 上面添加的更新可能会有所帮助

标签: asp.net-mvc asp.net-mvc-migration


【解决方案1】:

我找到了解决此问题的方法,但首先要了解一些历史。对于这个特殊的 MVC 项目,我们决定逐步开始实施 Razor。该应用程序有很多“模态”区域,这些区域通过 AJAX 调用来填充以获取局部视图。这些局部视图是第一个作为 Razor 视图实现的。后来,我们想使用 Razor 局部视图在标准 ASPX 视图页面中实现一个新功能,但是 ASPX 视图引擎无法渲染局部 Razor 视图,因此我没有使用 Razor 视图,而是在 App_Code 文件夹中添加了一个 MVC 帮助文件呈现特征的方法。这种方法是升级到 MVC4 后导致错误的原因。具有通过此方法呈现的功能的页面是我正在转换为 Razor 视图页面的页面,因此我今天意识到我需要做的就是将代码从该方法移动到 Razor 局部视图中。 这解决了问题,但是,我仍然认为这是 Razor 引擎中的一个错误,用于使用辅助方法进行渲染。

【讨论】:

    【解决方案2】:

    我将方法简化为:

    @helper RenderConnectButton(System.Web.Mvc.HtmlHelper helper, ContactTwitterHandleDto contactTwitterHandle, ContactFacebookAccountDto contactFacebookAccount) {
    
        <ul class="socialMedia inlineList">
            @if (contactTwitterHandle != null && contactTwitterHandle.IsValid.HasValue && contactTwitterHandle.IsValid.Value)
            {
                var tHandle = contactTwitterHandle.Handle;
    
                <li class="twitter">
                    <a class="btn" href="http://twitter.com/@tHandle" target="_blank">
                        <i></i>
                        <span class="label">@tHandle</span> 
                    </a>
                </li>
            }
    
        </ul>
    }
    

    如果我从该行中删除 @tHandle:

                <a class="btn" href="http://twitter.com/@tHandle" target="_blank">
    

    它会很好地解析。如果我将上面的 Url 放入变量中,则会出现错误。

    尝试解析 Url 字符串时失败。

    堆栈跟踪:

       at System.Web.WebPages.HelperPage.WriteAttributeTo(TextWriter writer, String name, PositionTagged`1 prefix, PositionTagged`1 suffix, AttributeValue[] values)
       at ASP.MvcSocialMediaHelpers.<>c__DisplayClass1.<RenderConnectButton>b__0(TextWriter __razor_helper_writer) in c:\OberonScrum\Branches\RazorUpgrade\Source\Web\App_Code\MvcSocialMediaHelpers.cshtml:line 83
       at System.Web.WebPages.HelperResult.ToString()
       at System.String.Concat(Object arg0, Object arg1)
       at ASP.views_contact_detail_aspx.__RenderMainContent(HtmlTextWriter __w, Control parameterContainer) in c:\OberonScrum\Branches\RazorUpgrade\Source\Web\Views\Contact\Detail.aspx:line 13
       at System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children)
       at ASP.views_shared_twocolumnleftmain_master.__Render__control1(HtmlTextWriter __w, Control parameterContainer) in c:\OberonScrum\Branches\RazorUpgrade\Source\Web\Views\Shared\TwoColumnLeftMain.Master:line 109
       at System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children)
       at System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children)
       at System.Web.Mvc.ViewPage.Render(HtmlTextWriter writer)
       at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
    

    [更新] 尝试使用 TagBuilder 解决该问题并使用 Html.Raw();得到了相同的结果。

    @helper RenderConnectButton(System.Web.Mvc.HtmlHelper helper, ContactTwitterHandleDto contactTwitterHandle, ContactFacebookAccountDto contactFacebookAccount) {
        <ul class="socialMedia inlineList">
            @if (contactTwitterHandle != null && contactTwitterHandle.IsValid.HasValue && contactTwitterHandle.IsValid.Value)
            {
                var tHandle = contactTwitterHandle.Handle;
                var a = new TagBuilder("a");
                a.Attributes.Add("href", "http://twitter.com/" + @tHandle);
                a.Attributes.Add("target", "_blank");
                a.Attributes.Add("class", "btn");
                a.InnerHtml = string.Format("<i></i><span class=\"label\">{0}</span>", @tHandle);
    
                <li class="twitter">
                    @Html.Raw(a.ToString())
                </li>
            }
        </ul>
    }
    

    【讨论】:

    • 有趣,错误发生在HelperPage.WriteAttributeTo,一个框架类/方法。我知道 MVC4 为具有空值的属性添加了一些复杂的支持。这里可能有一个错误。
    • 我也是这么想的。
    • 也许吧,但要在一个问题中发布很多信息。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-05-19
    • 2014-07-15
    • 2015-08-09
    • 1970-01-01
    • 2016-03-04
    • 2013-11-13
    • 2012-11-30
    相关资源
    最近更新 更多