6

我在 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>
}
4

2 回答 2

2

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

于 2012-05-17T15:17:00.217 回答
0

我将方法简化为:

@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>
}
于 2012-05-16T18:37:23.790 回答