Элемент модели, переданный в словарь, имеет тип "mvc.Models.ModelA", но для этого словаря требуется элемент модели типа "mvc.Models.ModelB"
У меня есть эта досадная ошибка в некоторых моих сборках.
В проекте нет ошибки, потому что, если я снова создам, проблема исчезнет. Сообщение появляется только при развертывании сайта на сервере Windows 2008 Server.
Сначала я подумал, что это может быть проблема с временными файлами, но это не так. Я развернул сборку в другую сеть, и ошибка все еще появляется.
Ошибка при случайных действиях сайта. В большинстве случаев сборки в порядке, но каждая 3-я или 4-я сборка создает ошибки времени выполнения.
Я использую WebdeploymentProject в режиме выпуска. Представления предварительно скомпилированы.
Это не В ASP.NET MVC я сталкиваюсь с неправильной ошибкой типа при рендеринге страницы с правильным типизированным объектом, поскольку представления имеют совершенно разные имена.
Как я могу отладить эту проблему или как я могу получить помощь для этого?
Вот мой WebDeploymentProject
<!--
Microsoft Visual Studio 2008 Web Deployment Project
http://go.microsoft.com/fwlink/?LinkID=104956
-->
<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>9.0.21022</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{E5E14CEB-0BCD-4203-9A5A-34ABA9C717EA}</ProjectGuid>
<SourceWebPhysicalPath>..\B2CWeb</SourceWebPhysicalPath>
<SourceWebProject>{3E632DB6-6DB3-4BD0-8CCA-12DE67165B48}|B2CWeb\B2CWeb.csproj</SourceWebProject>
<SourceWebVirtualPath>/B2CWeb.csproj</SourceWebVirtualPath>
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<OutputPath>.\Debug</OutputPath>
<EnableUpdateable>false</EnableUpdateable>
<UseMerge>true</UseMerge>
<SingleAssemblyName>B2CWeb_Build</SingleAssemblyName>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugSymbols>false</DebugSymbols>
<OutputPath>..\B2CWeb_Deploy\</OutputPath>
<EnableUpdateable>false</EnableUpdateable>
<UseMerge>true</UseMerge>
<SingleAssemblyName>B2C_Web</SingleAssemblyName>
<ContentAssemblyName>
</ContentAssemblyName>
<DeleteAppCodeCompiledFiles>false</DeleteAppCodeCompiledFiles>
</PropertyGroup>
<ItemGroup>
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath)\Microsoft\WebDeployment\v9.0\Microsoft.WebDeployment.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.WebDeployment.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="BeforeMerge">
</Target>
<Target Name="AfterMerge">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>
ИЗМЕНИТЬ
Спустя несколько месяцев эта проблема исчезла. У меня не было проблем уже более 1 года. Думаю, проблема снова наступит, когда никто этого не ожидает.
РЕДАКТИРОВАТЬ 2
... уже более 2 лет. Я такой счастливый чувак!
РЕДАКТИРОВАТЬ 3
Я просто прочитал статью о MSDN, и это звучит как проблема, которую я имел. У меня отключена отладка, но компиляция была "иногда неправильной". Поведение старого провайдера может быть проблемой. Но это просто догадывается.
Очень большие страницы, содержащие длинные интервалы HTML без серверных блоков (например, <% =% > ), могут привести к переполнению стека, когда включена компиляция отладки, которая приведет к сбою приложения. Обратите внимание, что при нашем тестировании его занимает страница с размером ~ 4x, которая создавала аналогичную проблему у старого провайдера, но в этом случае она вырывает все приложение, тогда как со старым провайдером он просто терпит неудачную страницу
Ответы
Ответ 1
Даже если типы совпадают, вы можете получить эту ошибку, когда null передается частичному представлению.
Вы можете исправить это, вызвав RenderPartial
с пустым ViewDataDictionary
следующим образом:
helper.RenderPartial("~/Views/Player/PlayerName.ascx", player, new ViewDataDictionary());
Для справки я нашел это решение на:
renderpartial с нулевой моделью передается неверный тип
Ответ 2
Частицы ASP.NET MVC
Прошла модель NULL!!!
@Html.Partial("PartialView", model: Model)
Ответ 3
Эта ошибка может возникать (и происходит), когда есть несоответствие между данными, которые метод действия контроллера подает на представление, и тип данных, которые ожидают представления. Обычно это не будет отображаться как ошибка сборки, даже с предварительно скомпилированными видами.
Например, если у меня есть метод...
public ActionResult Create()
{
// Do something
return View(new CustomerCreateViewModel());
}
... и Создать представление с атрибутом страницы...
<%@ Page ... Inherits="System.Web.Mvc.ViewPage<CustomerDetailsViewModel>" %>
... это будет компилироваться и создаваться без ошибок. Однако, когда я вызываю действие "Создать", я получаю желтый экран, потому что метод "Создать действие" выбрасывает данные одного типа, и представление ожидает данных другого типа. Вы можете проверить, соответствуют ли ваши типы...
Ответ 4
Вы абсолютно уверены, что это не имеет ничего общего с данными, передаваемыми в представление? Вы выполняете полную перестройку каждый раз?
Эти ошибки обычно возникают, потому что частичный вид пытается использовать модель представления, переданную в ViewPage, когда модель представления, переданная частичному представлению, равна нулю. Я понимаю, что вы подразумеваете, что ошибка каким-то образом вызвана процессом сборки, но я не вижу, как это будет возможно.
Возможно ли, что развернутый сайт использует другую базу данных, чем сайт, который вы запускали на вашей машине разработки, и могут ли данные (или отсутствие данных) в этой базе данных быть причиной проблемы?
Ответ 5
Создает ли скрипт какие-либо предупреждения или ошибки вообще?
Правильно ли настроены ваши зависимости? Например. в зависимости от моделей. Постройте данные о том, в каком порядке компилировать вещи, просмотрев указанные зависимости. Например. если вы измените модель, и представление скомпилировано до того, как у вас возникнет проблема...
Неужели это исчезнет, если вы не компилируете представления?
Кроме того, ваши представления наследуют System.Web.Mvc.ViewPage
или System.Web.Mvc.ViewPage<T>
, где T - ваша модель?
Ответ 6
Прежде чем назначить модель пользовательскому управлению из вашего представления, создайте экземпляр этого конкретного объекта в конструкторе модели/объекта.
Пример:
public class MainEntity
{
public SubEntity AssociatedEntity;
public MainEntity()
{
// This is where the instantiation happen.
AssociatedEntity = new SubEntity();
}
}
public class SubEntity
{
public string property1;
}
Ваша страница просмотра:
<%@ Page Title="" Language="C#"
MasterPageFile="~/Views/Shared/Site.Master"
Inherits="System.Web.Mvc.ViewPage<MyNamespace.Models.MainEntity>" %>
....
<%Html.RenderPartial("ucMyUserControl",Model.AssociatedEntity);
....
Пользовательский контроль:
<%@ Control Language="C#"
Inherits="System.Web.Mvc.ViewUserControl<MyNamespace.Models.SubEntity>" %>
....
<%Html.TextBoxFor(m=>m.Property1);
Ответ 7
Если у вас есть переопределяющая папка Views, где существуют несколько партиций с одним и тем же именем (одно переопределение другого с тем же именем), обязательно обновите тип модели на каждом представлении или вы можете получить эта ошибка.
Ответ 8
У меня появилось следующее сообщение об ошибке
Элемент модели, переданный в словарь, имеет тип 'System.Linq.Enumerable + WhereSelectListIterator2 [MyProject.Models.A, MyProject.Models.B]', но для этого словаря требуется элемент модели типа 'System.Collections.Generic.List1 [MyProject.Models.B]'.
со следующим кодом
IEnumerable<B> list_B;
...
IEnumerable<A> list_A = Repo.GetListOfType_A();
list_B = list_A.Select(x => new B { Number = x.Number, Name = x.Name });
...
return View(list_B);
и я понятия не имею, что такое тип
System.Linq.Enumerable + WhereSelectListIterator2 [MyProject.Models.A, MyProject.Models.B]
в любом случае ошибка исчезает, когда я добавляю .ToList()
в конец
IEnumerable<B> list_B;
...
IEnumerable<A>list_A = Repo.GetListOfType_A();
list_B = list_A.Select(x => new B { Number = x.Number, Name = x.Name }).ToList(); // here
...
return View(list_B);
Надеюсь, что это поможет кому-то еще.