Razor helper method does not work after upgrading from MVC 3 to 4

I have a helper method in a file in the App_Code directory. The method works fine in MVC 3, but after upgrading to MVC 4 it is not. It does not work in the first block of @if () ...

[Edit] This looks like a parsing error in the Razor engine. I get the error "Link to an object that is not set to an instance of the object" when all my objects and their properties are NOT null. I think I will have to contact Microsoft directly.

[Change] An error message is an old object reference not installed on an object instance. This is strange because each AND object in the condition is valid, not null.

@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> } 

[UPDATE] I changed the code a bit, and now it's even weirder. I get the same error as above in the line:

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

contactTwitterHandle and contactTwitterHandle.Handle are both NOT null.

 @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> } 
+6
source share
2 answers

I found work around this problem, but first a bit of history. For this MVC project, we decided to gradually introduce Razor. The application has many โ€œmodalโ€ areas that are populated by calling AJAX to get a partial look. These partial views were the first to be implemented as Razor sorts. Later, we wanted to implement a new function on the standard ASPX view page using a partial Razor view, but the ASPX view mechanism cannot display a partial Razor view, so instead of using the Razor view, I added an auxiliary MVC file to the App_Code folder with a method that displays this function. This method throws an error after upgrading to MVC4. The page with the function represented by this method is what I convert to the Razor view page, so I realized today that all I need to do is translate the code from this method into a partial Razor view. This fixed the problem, but I still claim that this is a bug in the Razor engine for rendering using helper methods.

+2
source

I applied the method to this:

 @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> } 

If I remove @tHandle from the line:

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

He will understand perfectly. If I put Url above in a variable, I will get an error.

Unable to parse a string that is Url.

Stack trace:

  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) 

[UPDATE] Tried to work with the problem using TagBuilder and rendering using Html.Raw (); got the same result.

 @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> } 
0
source

Source: https://habr.com/ru/post/915922/


All Articles