Аргументы типа не могут быть выведены из использования. Попробуйте явно указать аргументы типа

Может кто-нибудь прояснить кое-что для меня. В моем приложении ASP.NET MVC 2 у меня есть класс BaseViewModel, который включает следующий метод:

public virtual IDictionary<string, object> GetHtmlAttributes<TModel, TProperty>
                        (Expression<Func<TModel, TProperty>> propertyExpression)
{
    return new Dictionary<string, object>();
}

Идея состоит в том, что каждая дочерняя модель просмотра может переопределить этот метод и предоставить подходящий набор атрибутов html, основанный на некоторой логике, для отображения в представлении:

<%: Html.TextBoxFor(model => model.MyProperty, Model.GetHtmlAttributes
                                                 (model => model.MyProperty)) %>

Однако при использовании, как в строке выше, я получаю ошибку компиляции, когда нажимаю на представление:

Аргументы типа для метода «...BaseViewModel.GetHtmlAttributes<TModel,TProperty> Expression<System.Func<TModel,TProperty>)» не могут быть выведены из использования. Попробуйте явно указать аргументы типа.

Я должен сделать следующее:

<%: Html.TextBoxFor(model => model.MyProperty, Model.GetHtmlAttributes
                             <ChildModel, string>(model => model.MyProperty)) %>

Я просто ищу некоторую ясность относительно того, как он пытается вывести тип, у него нет проблем с этим в методе расширения HtmlHelper/TextBoxFor?

Это потому, что HtmlHelper в представлении будет автоматически относиться к тому же типу, который указан в ViewUserControl вверху страницы, тогда как мой код может относиться к любому типу, унаследованному от BaseViewModel? Можно ли написать это таким образом, чтобы он мог вывести мои типы модели/свойства?


person Veli Gebrev    schedule 11.02.2011    source источник
comment
Святые горизонтальные полосы прокрутки Бэтмен!   -  person dreadwail    schedule 12.02.2011
comment
Да полностью. Абсурдно, что на наших 30 мониторах мы получаем всего 6,5 за прокрутку кода туда-сюда в этих крошечных окнах. Давай, парни из SA, возьми свои венчурные деньги и получи динамическое изменение размера страницы!   -  person Slaggg    schedule 13.02.2011


Ответы (8)


В вашем примере компилятор не может узнать, какой тип должен быть TModel. Вы можете сделать что-то близкое к тому, что вы, вероятно, пытаетесь сделать с помощью метода расширения.

static class ModelExtensions
{
   public static IDictionary<string, object> GetHtmlAttributes<TModel, TProperty>
      (this TModel model, Expression<Func<TModel, TProperty>> propertyExpression)
   {
       return new Dictionary<string, object>();
   }
}

Но я думаю, у вас не было бы ничего похожего на virtual.

ИЗМЕНИТЬ:

На самом деле вы можете сделать virtual, используя самореферентные дженерики:

class ModelBase<TModel>
{
    public virtual IDictionary<string, object> GetHtmlAttributes<TProperty>
        (Expression<Func<TModel, TProperty>> propertyExpression)
    {
        return new Dictionary<string, object>();
    }
}

class FooModel : ModelBase<FooModel>
{
    public override IDictionary<string, object> GetHtmlAttributes<TProperty>
        (Expression<Func<FooModel, TProperty>> propertyExpression)
    {
        return new Dictionary<string, object> { { "foo", "bar" } };
    }
}
person svick    schedule 18.04.2011
comment
В данном случае это работает нормально, но неприемлемо для некоторых расширений HtmlHelper. Действительно, я создал следующее расширение: public static IHtmlContent EnumCheckBoxListFor<TModel, TEnum>(this IHtmlHelper<TModel> htmlHelper, Expression<Func<TModel, IEnumerable<TEnum>>> expression, object htmlAttributes = null) . В этом случае я не могу использовать обходной путь виртуального/переопределения (и я не вижу никакого чистого решения). Обратите внимание, что когда я вызываю его в своем представлении, тип модели может быть выведен, а тип Enum - нет. - person Ishikawa; 26.09.2019

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

Я делал это:

@Html.HiddenFor(Model.Foo.Bar.ID)

То, что сработало для меня, изменилось на это:

@Html.HiddenFor(m => m.Foo.Bar.ID)

(где «m» — произвольная строка для представления объекта модели)

person inanutshellus    schedule 27.10.2012

У меня была такая же проблема, мое решение:
В файле web.config:

<compilation debug="true>
пришлось заменить на
<compilation debug="true" targetFramework="4.0">

person Jim    schedule 16.12.2011
comment
Спасибо БОЛЬШОЕ Джим! Вы спасли мой день, я несколько дней гуглил и не нашел решения по основным вопросам, но затем нашел ваше здесь, в небольшом комментарии! Я использую VS 2012, который поставляется с MVC 4.0, и да, добавление targetFramework=4.0 решило проблемы с красными линиями в ViewBag, Html.TextboxFor и т. д. - person Nestor; 04.12.2012
comment
Я открыл новый Вопрос с более подходящим заголовком, использовал ваш ответ и получил за это признание. Надеюсь, это поможет другим. - person Nestor; 04.12.2012
comment
Спасибо, Джим, ты спас мой день. Можете ли вы объяснить, почему эта целевая структура важна? как ты это понял? - person Vincent; 03.01.2013

Эта ошибка также связана с проблемой кеша.

У меня была та же проблема, и она была решена просто очисткой и повторным созданием решения.

person Zanon    schedule 11.01.2016
comment
Для меня это также была проблема с кэшированием, но она была решена только после перезапуска Visual Studio. Для меня это произошло после обновления пространств имен моделей, на которые ссылались. - person WillemdeKok; 26.04.2017
comment
Наткнулся на это, и это тоже кешировалось для меня! - person lozzajp; 04.10.2017

Компилятор С# имеет только лямбда

arg => arg.MyProperty

для вывода типа arg(TModel) типа arg.MyProperty(TProperty). Это невозможно.

person Ziav    schedule 12.04.2011

На самом деле я искал аналогичную ошибку, и Google отправил меня сюда на этот вопрос. Ошибка была:

Аргументы типа для метода «IModelExpressionProvider.CreateModelExpression(ViewDataDictionary, Expression>)» не могут быть выведены из использования

Я потратил, может быть, 15 минут, пытаясь понять это. Это происходило внутри файла представления Razor .cshtml. Мне пришлось комментировать части кода представления, чтобы добраться до того места, где он лаял, поскольку компилятор мало чем помогал.

<div class="form-group col-2">
    <label asp-for="Organization.Zip"></label>
    <input asp-for="Organization.Zip" class="form-control">
    <span asp-validation-for="Zip" class="color-type-alert"></span>
</div>

Вы можете заметить это? Да... Я перепроверил это, может быть, дважды и сначала не понял!

Обратите внимание, что свойство ViewModel равно Zip, хотя должно быть Organization.Zip. Вот оно.

Так что перепроверьте исходный код вашего представления... :-)

person Leniel Maccaferri    schedule 13.06.2020
comment
Спасибо за это. У меня была такая же проблема, и этот ответ мне очень помог. Похоже, что использование несуществующего имени свойства в asp-for или asp-validation-for вызывает это исключение. - person Aldinei Sampaio; 18.08.2020

В случае, если это поможет, я столкнулся с этой проблемой при передаче null в параметр для общего TValue, чтобы обойти это, вы должны указать свои нулевые значения:

(string)null

(int)null

и Т. Д.

person DevDave    schedule 28.02.2013

Вы имеете в виду тип, а не экземпляр. Сделайте «Модель» строчными буквами в примере во втором и четвертом примерах кода.

Model.GetHtmlAttributes

должно быть

model.GetHtmlAttributes
person Slaggg    schedule 13.02.2011
comment
спасибо за предложение, но мне нужно дать ему конкретный экземпляр объекта модели (открыл свойство модели представления). 'model' на самом деле не существует в контексте параметра htmlAttributes помощника TextBoxFor. - person Veli Gebrev; 14.02.2011