16

I'm using Razor Helpers in a C# Web Forms application.

The following code compiles and renders A-OK when called:

@helper MemberListItem(string firstname, string lastname, string avatarUrl)
{
    <li>
        @firstname @lastname
        @avatarUrl
    </li>
}

Output (two calls to the helper):

<li>Bryan Arnold ../../Resources/Images/Placeholders/generic-user-image.jpg</li>
<li>Doug Bland ../../Resources/Images/Placeholders/generic-user-image.jpg</li>

But when I change the helper so that avatarUrl is placed in the src attribute of an img tag, I get a NullReferenceException on firstname. Yes, the NullReferenceException is on firstname.

The following code compiles but throws a NRE when called:

@helper MemberListItem(string firstname, string lastname, string avatarUrl)
{
    <li>
        @firstname @lastname
        <img src="@avatarUrl"/>
    </li>
}

Keep in mind that I am not changing a thing besides the placement of @avatarUrl in the helper.

How do I get the image to display?

Update 1: I have also tried wrapping my img code in <text></text> (to no avail):

<li>
    @firstname @lastname
    <text>
        <img src="@avatarUrl"/>
    </text>
</li>

Update 2: Here is the error:

Object reference not set to an instance of an object.

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. 

Exception Details: System.NullReferenceException: Object reference not set to an instance of an object.

Source Error: 

Line 11: {
Line 12:     <li>
Line 13:         @firstname @lastname
Line 14:         <img src="@avatarUrl"/>
Line 15:     </li>

Source File: RazorHelpers\Family.cshtml    Line: 13 

Update 3: I forgot to mention that I am defining the @helper in a separate file. Then, I am calling that helper from an aspx template like this:

<%= @HelperFile.Helper(parameters).ToString() %>

Also, I think @Luaan might be on to something. I have tried fiddling with ~ for relative pathing to my image files, thinking that Razor might be throwing a NRE because it cannot locate the file. It would appear that no setup with ~ works in my project.

With a static file path:

This works:

<img src="/Resources/Images/Placeholders/generic-user-image.jpg"/>

This doesn't (NullReferenceException):

<img src="~/Resources/Images/Placeholders/generic-user-image.jpg"/>

With a dynamic file path:

This doesn't work (NullReferenceException):

<img src="@avatarUrl"/>

Neither does this (NullReferenceException):

<img src="~@avatarUrl"/>

Note: The Resources directory is in the root of my website.

Update 4:

I have deserted my original helper (the one mentioned at the beginning of this question) and gone with a pure ASPX template due to time constraints with my project. However, I am trying to use a Razor helper for a different feature in this application and I am having the same problem I have described prior.

Here is a similar helper (source and compiled code). The helper is supposed to display a list of links that allow the user to sign-up/sign-in for my application using various identity providers (google, facebook, twitter, yahoo). The story is the same here; the helper executes without an error when I just print the img src but it throws a NullReferenceException when I put the img src into an actual <img/> tag.

Source:

@helper ListGroupGrid(IEnumerable<ExternalIdentityProvider> providers) {
    <div>
        @foreach(var provider in providers){
            @provider.Name
            <img src="@provider.IconUrl"/>
        }
    </div>
}

Compiled code (from Temporary ASP.NET Files in c:\Windows):

#pragma checksum "C:\Users\Public\Documents\VisualStudioProjects\OnlineStable\Aqha\App_Code\RazorHelpers\IdentityProvider.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "46B0FEE2042706017F4AE53D4EA612F3E73EDF8B"
//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by a tool.
//     Runtime Version:4.0.30319.18052
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

namespace ASP.RazorHelpers {
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using System.Net;
    using System.Web;
    using System.Web.Helpers;
    using System.Web.Security;
    using System.Web.UI;
    using System.Web.WebPages;
    using System.Web.WebPages.Html;

    #line 1 "C:\Users\Public\Documents\VisualStudioProjects\OnlineStable\Aqha\App_Code\RazorHelpers\IdentityProvider.cshtml"
    using Aqha.DatabaseHelpers;

    #line default
    #line hidden

    #line 2 "C:\Users\Public\Documents\VisualStudioProjects\OnlineStable\Aqha\App_Code\RazorHelpers\IdentityProvider.cshtml"
    using Aqha.RazorExtensions;

    #line default
    #line hidden

    #line 3 "C:\Users\Public\Documents\VisualStudioProjects\OnlineStable\Aqha\App_Code\RazorHelpers\IdentityProvider.cshtml"
    using DevExpress.Utils.Drawing.Helpers;

    #line default
    #line hidden


    public class IdentityProvider : System.Web.WebPages.HelperPage {

#line hidden

#line 5 "C:\Users\Public\Documents\VisualStudioProjects\OnlineStable\Aqha\App_Code\RazorHelpers\IdentityProvider.cshtml"
public static System.Web.WebPages.HelperResult ListGroupGrid(IEnumerable<IdentityProviderData.ExternalIdentityProvider> providers) {
#line default
#line hidden
return new System.Web.WebPages.HelperResult(__razor_helper_writer => {

#line 5 "C:\Users\Public\Documents\VisualStudioProjects\OnlineStable\Aqha\App_Code\RazorHelpers\IdentityProvider.cshtml"



#line default
#line hidden
BeginContext(__razor_helper_writer, "~/App_Code/RazorHelpers/IdentityProvider.cshtml", 202, 11, true);

WriteLiteralTo(__razor_helper_writer, "    <div>\r\n");

EndContext(__razor_helper_writer, "~/App_Code/RazorHelpers/IdentityProvider.cshtml", 202, 11, true);


#line 7 "C:\Users\Public\Documents\VisualStudioProjects\OnlineStable\Aqha\App_Code\RazorHelpers\IdentityProvider.cshtml"


#line default
#line hidden

#line 7 "C:\Users\Public\Documents\VisualStudioProjects\OnlineStable\Aqha\App_Code\RazorHelpers\IdentityProvider.cshtml"
         foreach(var provider in providers){


#line default
#line hidden
BeginContext(__razor_helper_writer, "~/App_Code/RazorHelpers/IdentityProvider.cshtml", 272, 13, false);


#line 8 "C:\Users\Public\Documents\VisualStudioProjects\OnlineStable\Aqha\App_Code\RazorHelpers\IdentityProvider.cshtml"
WriteTo(__razor_helper_writer, provider.Name);


#line default
#line hidden
EndContext(__razor_helper_writer, "~/App_Code/RazorHelpers/IdentityProvider.cshtml", 272, 13, false);


#line 8 "C:\Users\Public\Documents\VisualStudioProjects\OnlineStable\Aqha\App_Code\RazorHelpers\IdentityProvider.cshtml"



#line default
#line hidden
BeginContext(__razor_helper_writer, "~/App_Code/RazorHelpers/IdentityProvider.cshtml", 287, 16, true);

WriteLiteralTo(__razor_helper_writer, "            <img");

EndContext(__razor_helper_writer, "~/App_Code/RazorHelpers/IdentityProvider.cshtml", 287, 16, true);

WriteAttributeTo(__razor_helper_writer, "src", Tuple.Create(" src=\"", 303), Tuple.Create("\"", 326)

#line 9 "C:\Users\Public\Documents\VisualStudioProjects\OnlineStable\Aqha\App_Code\RazorHelpers\IdentityProvider.cshtml"
, Tuple.Create(Tuple.Create("", 309), Tuple.Create<System.Object, System.Int32>(provider.IconUrl

#line default
#line hidden
, 309), false)
);

BeginContext(__razor_helper_writer, "~/App_Code/RazorHelpers/IdentityProvider.cshtml", 327, 4, true);

WriteLiteralTo(__razor_helper_writer, "/>\r\n");

EndContext(__razor_helper_writer, "~/App_Code/RazorHelpers/IdentityProvider.cshtml", 327, 4, true);


#line 10 "C:\Users\Public\Documents\VisualStudioProjects\OnlineStable\Aqha\App_Code\RazorHelpers\IdentityProvider.cshtml"
        }


#line default
#line hidden
BeginContext(__razor_helper_writer, "~/App_Code/RazorHelpers/IdentityProvider.cshtml", 342, 12, true);

WriteLiteralTo(__razor_helper_writer, "    </div>\r\n");

EndContext(__razor_helper_writer, "~/App_Code/RazorHelpers/IdentityProvider.cshtml", 342, 12, true);


#line 12 "C:\Users\Public\Documents\VisualStudioProjects\OnlineStable\Aqha\App_Code\RazorHelpers\IdentityProvider.cshtml"


#line default
#line hidden
});

#line 12 "C:\Users\Public\Documents\VisualStudioProjects\OnlineStable\Aqha\App_Code\RazorHelpers\IdentityProvider.cshtml"
}
#line default
#line hidden


        public IdentityProvider() {
        }

        protected static ASP.global_asax ApplicationInstance {
            get {
                return ((ASP.global_asax)(Context.ApplicationInstance));
            }
        }
    }
}

Update 5: I did some more testing. To illustrate the issue as clearly as possible, I eliminated all input parameters and extra markup.

Consider the following three helpers:

@helper BaseCase() {
    <img src="/Resources/Images/Placeholders/generic-user-image.jpg"/>
}

@helper VariableBaseCase() {
    var src = "/Resources/Images/Placeholders/generic-user-image.jpg";
    <img src="/Resources/Images/Placeholders/generic-user-image.jpg"/>
    <text>the source is @src</text>
}

@helper Variable() {
    var src = "/Resources/Images/Placeholders/generic-user-image.jpg";
    <img src="@src"/>
    <text>the source is @src</text>
}

When I call the first two helpers from an ASPX, they display output (and the images appear normally) without exception:

<%= RazorHelpers.ImageTest.BaseCase().ToString() %>
<%= RazorHelpers.ImageTest.VariableBaseCase().ToString() %>

When I call the last helper, I get the same error I have been getting.

<%= RazorHelpers.ImageTest.Variable().ToString() %>

I hope now I am correct in believing that this is somehow a relative path issue. How do I get Razor to display images with dynamic src properties in my Web Forms application?

10
  • Are you absolutely sure it's not null or that there's nothing else going on? Using your exact method, and passing the two sets of data to it, I'm getting the correct output. I should mention that's within an MVC application. Commented Nov 12, 2013 at 18:02
  • I am positive that it's not null. My base case shows that. Commented Nov 12, 2013 at 18:18
  • Well, there is certainly a null somewhere. I just know it isn't my data. Also, I'm using Web Forms. Commented Nov 12, 2013 at 18:26
  • Is there a way to see generated C# file? You might find it in ASP.NET temp files. Or you can download and see output of RazorGenerator. Commented Nov 22, 2013 at 19:05
  • I am confused. I'm using VS 2012 + update 3. I created a new Empty Web Form Application. I added Razor 3 and WebPages 3 nuget packages to my project. I added a CSHTML file in my project. I typed your codes there. I ran application without any error and result was correct and well formed HTML. Did I do something different? Commented Nov 24, 2013 at 16:49

6 Answers 6

2

I just had a simular problem (mvc.net 4). I bypassed it this way:

error code:

<input name="ItemUID" type="hidden" value="@ItemUID" />

working code:

<input name="ItemUID" type="hidden" @("value=")"@ItemUID" />
Sign up to request clarification or add additional context in comments.

1 Comment

very interesting.. I'll have to check this out further
1

Razor parser will not parse your HTML correctly because it looks for sections at a time. In this case it assumes the whole block () is HTML

Try surrounding your HTML with < text> HTML here < / text> Makes it a lot easier to read and interpret by the parser

4 Comments

Thanks, I just tried that but it didn't help. The NRE is still occurring.
Try wrapping the <img src="AND "/> separately. I'm thinking that your @avatarUrl is not being rendered correctly
That doesn't help either. :(
Could you tell me the error you get? because I just tried your original code on my MVC 4 razor project and it worked fine
1

I believe that Razor tries to make sure the URL you're passing to img src is valid. Are you sure the files actually exist in the correct relative directory? Maybe you could try passing the URL in root-relative format (ie. "~/Resources/Images/Placeholders/generic-user-image.jpg"). If that doesn't help, you could try rendering the image using @Html.Image or @Html.Raw. And if that doesn't help, try @Url.Content(avatarUrl), but that's really trying hard :)

6 Comments

Related to that, are you defining the @helper in an actual page, or some sort of helper "library"? It might be throwing null on some kind of page reference when trying to resolve the URL. Just as a test, try moving the @helper to the page where you're actually using it.
Did some testing with hard-coded values. This works: <img src="/Resources/Images/Placeholders/generic-user-image.jpg"/>. This throws a NRE: <img src="~/Resources/Images/Placeholders/generic-user-image.jpg"/>
Also, this doesn't work (from my question) <img src="@avatarUrl"/>. This doesn't work either (added ~): <img src="~@avatarUrl"/>. For the latter, the value for src would be ~/Resources/Images/Placeholders/generic-user-image.jpg
It would appear that ~ does not work at all for me. Is that a construct of Razor or of MVC? (I'm using Web Forms)
Also, I am defining the @helper in a separate file. Then, I am calling that helper from an aspx template like this: <%= @HelperFile.Helper(parameters).ToString() %>
|
1

It seems you are not the only one with the problem. You MVC version (MVC2 I assume) has a bug that raises and exception when it calls WriteAttributeTo. This problem is mentioned in following stackoverflow question "Null reference exception in WriteAttributeTo method".

Only reasonable solution is to use a newer version. probably MVC3 (with update1). Your .NET version is 4.0+ so it will not be a problem.

1 Comment

Sorry, my bad. I meant razor runtime. Update your razor runtime.
1

This rings a bell somewhere. Try the below with the parentheses around the variables, it seems to help the Razor engine out a bit:

@helper MemberListItem(string firstname, string lastname, string avatarUrl)
{
    <li>
        @(firstname) @(lastname)
        <img src="@(avatarUrl)" />
    </li>
}

1 Comment

This fixed a problem I was having. I wasn't using img tags in my helper but was writing attributes using @. Thanks!
0

A bit late but I had the same problem and took me several hours to solve. What fixed the issue for me was the following:

string attributeValue= "some value";

string attributeExpression= "attributeName=" + attributeValue;

<div class="" id="" @attributeExpression></div>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.