Strange NullRefereneceException в помощнике Razor

Я использую помощников Razor в приложении С# Веб-формы.

Следующий код компилирует и отображает A-OK при вызове:

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

Выход (два вызова помощника):

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

Но когда я меняю помощника так, что avatarUrl помещается в атрибут src тега img, я получаю a NullReferenceException on firstname. Да, NullReferenceException находится на firstname.

Следующий код компилируется, но выдает NRE при вызове:

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

Имейте в виду, что я не изменяю вещь, кроме размещения @avatarUrl в помощнике.

Как мне отобразить изображение?

Обновление 1: Я также попытался обернуть мой код img в <text></text> (безрезультатно):

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

Обновление 2: Вот ошибка:

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 

Обновление 3: Я забыл упомянуть, что я определяю @helper в отдельном файле. Затем я вызываю этот помощник из шаблона aspx следующим образом:

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

Кроме того, я думаю, что @Luaan может что-то сказать. Я пробовал играть с ~ для относительного пути к моим файлам изображений, думая, что Razor может выбросить NRE, потому что он не может найти файл. Похоже, что никакая настройка с ~ не работает в моем проекте.

Со статическим пути к файлу:

Это работает:

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

Это не (исключение NullReferenceException):

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

С динамическим пути к файлу:

Это не работает (исключение NullReferenceException):

<img src="@avatarUrl"/>

Также это (исключение NullReferenceException):

<img src="[email protected]"/>

Примечание. Каталог Resources находится в корне моего сайта.

Обновление 4:

Я покинул свой оригинальный помощник (тот, который упоминается в начале этого вопроса), и ушел с чистым шаблоном ASPX из-за нехватки времени с моим проектом. Тем не менее, я пытаюсь использовать помощник Razor для другой функции в этом приложении, и у меня такая же проблема, как я описал ранее.

Вот аналогичный помощник (исходный и скомпилированный код). Предполагается, что помощник отобразит список ссылок, которые позволяют пользователю регистрироваться/регистрироваться для моего приложения, используя различные поставщики удостоверений (google, facebook, twitter, yahoo). История здесь же; помощник выполняется без ошибки, когда я просто печатаю img src, но он бросает исключение NullReferenceException, когда я помещаю img src в фактический тег <img/>.

Источник:

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

Скомпилированный код (из временных файлов ASP.NET в 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));
            }
        }
    }
}

Обновление 5: Я сделал еще несколько тестов. Чтобы проиллюстрировать проблему как можно яснее, я исключил все входные параметры и дополнительную разметку.

Рассмотрим следующие три помощника:

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

Когда я вызываю первые два помощника из ASPX, они выводят вывод (и изображения появляются нормально) без исключения:

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

Когда я вызываю последнего помощника, я получаю ту же ошибку, которую я получаю.

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

Надеюсь, теперь я прав, полагая, что это как-то относительный путь. Как заставить Razor отображать изображения с динамическими свойствами src в моем приложении Web Forms?

Ответы

Ответ 1

Парсер Razor не будет правильно анализировать ваш HTML-код, потому что он ищет разделы за раз. В этом случае предполагается, что весь блок() является HTML

Попробуйте окружить свой HTML с помощью < текст > HTML здесь </текст > Делает это намного легче читать и интерпретировать парсером

Ответ 2

Я считаю, что Razor пытается убедиться, что URL, который вы передаете img src, действителен. Вы уверены, что файлы действительно существуют в правильном относительном каталоге? Возможно, вы могли бы попробовать передать URL-адрес в корневом формате (т.е. "~/Resources/Images/Placeholders/generic-user-image.jpg"). Если это не поможет, вы можете попробовать выполнить изображение с помощью @Html.Image или @Html.Raw. И если это не поможет, попробуйте @Url.Content(avatarUrl), но это действительно сложно:)

Ответ 3

Кажется, вы не единственная проблема. Вы MVC-версия (MVC2, я предполагаю) имеет ошибку, которая вызывает и исключение, когда она вызывает WriteAttributeTo. Эта проблема упоминается в следующем вопросе stackoverflow "Исключение Null ссылки в методе WriteAttributeTo".

Только разумное решение - использовать более новую версию. вероятно MVC3 (с обновлением1). Ваша версия .NET 4.0+, поэтому это не будет проблемой.

Ответ 4

Это звонит где-нибудь. Попробуйте использовать приведенные ниже скобки вокруг переменных, похоже, немного помогает движку Razor:

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

Ответ 5

У меня просто была проблема с simular (mvc.net 4). Я обошел его так:

код ошибки:

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

рабочий код:

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