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?
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. – Distortionnull
. My base case shows that. – Tartarnull
somewhere. I just know it isn't my data. Also, I'm using Web Forms. – Tartar#error
directive somewhere close to your function and try to compile. It will give an error and will show you generated code for your page. I need to see that to understand this situation – Parmenter#error
but I didn't see any special output. I updated my question with the compiled code for an example helper. – Tartar