Странное исключение NullRefereneceException в помощнике Razor

Я использую Razor Helpers в приложении C# Web Forms.

Следующий код компилируется и отображается 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, я получаю NullReferenceException на 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="~@avatarUrl"/>

Примечание. Каталог 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?


person Jonathan Wilson    schedule 12.11.2013    source источник
comment
Вы абсолютно уверены, что это не null или что больше ничего не происходит? Используя ваш точный метод и передав ему два набора данных, я получаю правильный результат. Я должен упомянуть, что это в приложении MVC.   -  person John H    schedule 12.11.2013
comment
Я уверен, что это не null. Мой базовый случай показывает это.   -  person Jonathan Wilson    schedule 12.11.2013
comment
Ну, где-то определенно есть null. Я просто знаю, что это не мои данные. Кроме того, я использую веб-формы.   -  person Jonathan Wilson    schedule 12.11.2013
comment
Есть ли способ увидеть сгенерированный файл С#? Вы можете найти его во временных файлах ASP.NET. Или вы можете скачать и посмотреть вывод RazorGenerator.   -  person Akash Kava    schedule 22.11.2013
comment
Я смущен. Я использую VS 2012 + обновление 3. Я создал новое пустое приложение веб-формы. Я добавил пакеты nuget Razor 3 и WebPages 3 в свой проект. Я добавил файл CSHTML в свой проект. Я набрал ваши коды там. Я запустил приложение без каких-либо ошибок, и результат был правильным и хорошо сформированным HTML. Я сделал что-то другое?   -  person Perseus    schedule 24.11.2013
comment
Может быть, вы сделали. Я не уверена. У меня было много подобных случаев с NullReferenceException. Наверное, я что-то делаю по незнанию :(   -  person Jonathan Wilson    schedule 25.11.2013
comment
Я запускал ваши коды на Razor 2 и WebPages 2 (на этот раз версии 2, а не 3). Ошибок тоже не было. Эта ошибка не связана с движком Razor. Что-то произошло до этапа рендеринга представления.   -  person Perseus    schedule 25.11.2013
comment
не могли бы вы попробовать добавить директиву #error где-нибудь рядом с вашей функцией и попытаться скомпилировать. Он выдаст ошибку и покажет вам сгенерированный код для вашей страницы. Мне нужно увидеть это, чтобы понять эту ситуацию   -  person Erdogan Kurtur    schedule 25.11.2013
comment
@эдокан. Я сделал то, что вы сказали, с #error, но я не увидел особого результата. Я обновил свой вопрос скомпилированным кодом для примера помощника.   -  person Jonathan Wilson    schedule 26.11.2013
comment
См. проблему github.com/RazorGenerator/RazorGenerator/issues/57.   -  person mems    schedule 10.12.2018


Ответы (6)


У меня была похожая проблема (mvc.net 4). Я обошел это так:

код ошибки:

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

рабочий код:

<input name="ItemUID" type="hidden" @("value=")"@ItemUID" />
person Doron Saar    schedule 21.10.2015
comment
очень интересно..надо еще посмотреть - person Jonathan Wilson; 21.10.2015

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

Попробуйте окружить HTML-код ‹ text> HTML здесь ‹ / text>. Это значительно упрощает чтение и интерпретацию синтаксическим анализатором.

person Jack Jiang    schedule 12.11.2013
comment
Спасибо, я только что попробовал это, но это не помогло. NRE все еще происходит. - person Jonathan Wilson; 12.11.2013
comment
Попробуйте обернуть ‹img src=AND /› отдельно. Я думаю, что ваш @avatarUrl отображается неправильно - person Jack Jiang; 12.11.2013
comment
Это тоже не помогает. :( - person Jonathan Wilson; 12.11.2013
comment
Не могли бы вы сказать мне ошибку, которую вы получаете? потому что я только что попробовал ваш исходный код в своем проекте бритвы MVC 4, и он работал нормально - person Jack Jiang; 12.11.2013

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

person Luaan    schedule 25.11.2013
comment
В связи с этим вы определяете @helper на реальной странице или в какой-то вспомогательной библиотеке? Это может быть нуль для какой-то ссылки на страницу при попытке разрешить URL-адрес. Просто в качестве теста попробуйте переместить @helper на страницу, где вы его используете. - person Luaan; 25.11.2013
comment
Провел некоторое тестирование с жестко запрограммированными значениями. Это работает: <img src="/Resources/Images/Placeholders/generic-user-image.jpg"/>. Это вызывает NRE: <img src="~/Resources/Images/Placeholders/generic-user-image.jpg"/> - person Jonathan Wilson; 26.11.2013
comment
Кроме того, это не работает (из моего вопроса) <img src="@avatarUrl"/>. Это тоже не работает (добавлено ~): <img src="~@avatarUrl"/>. В последнем случае значение src будет равно ~/Resources/Images/Placeholders/generic-user-image.jpg. - person Jonathan Wilson; 26.11.2013
comment
Похоже, ~ у меня вообще не работает. Это конструкция Razor или MVC? (Я использую веб-формы) - person Jonathan Wilson; 26.11.2013
comment
Кроме того, я определяю @helper в отдельном файле. Затем я вызываю этот помощник из шаблона aspx следующим образом: <%= @HelperFile.Helper(parameters).ToString() %> - person Jonathan Wilson; 26.11.2013
comment
Теперь, когда я увидел ваш пример кода, я думаю, что проблема может быть связана с использованием помощников Razor в коде WebForms. Razor пытается разрешить URL-адрес, используя WebPageContext/WebPage, которые имеют значение null (вместо этого WebForms использует HttpContext/Page). Что касается исправления, вы можете попробовать вызвать (HttpContext.Current.CurrentHandler as Page).ResolveUrl(avatarUrl) при создании образа src. Если это работает, вы можете превратить это в помощника, чтобы упростить его использование (или передать экземпляр Page своему помощнику). Если это не сработает, вы, вероятно, застряли с необходимостью писать HTML вручную, используя @Html.Raw или что-то подобное. - person Luaan; 26.11.2013

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

Единственным разумным решением является использование более новой версии. возможно MVC3 (с update1). У вас версия .NET 4.0+, так что проблем не будет.

person Erdogan Kurtur    schedule 26.11.2013
comment
Извини, я виноват. Я имел в виду время выполнения бритвы. Обновите среду выполнения бритвы. - person Erdogan Kurtur; 27.11.2013

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

@helper MemberListItem(string firstname, string lastname, string avatarUrl)
{
    <li>
        @(firstname) @(lastname)
        <img src="@(avatarUrl)" />
    </li>
}
person rhughes    schedule 26.11.2013
comment
Это устранило проблему, с которой я столкнулся. Я не использовал теги img в своем помощнике, но писал атрибуты, используя @. Спасибо! - person Joel Malone; 16.09.2015

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

string attributeValue= "some value";

string attributeExpression= "attributeName=" + attributeValue;

<div class="" id="" @attributeExpression></div>
person Panos    schedule 29.04.2020