System.InvalidOperationException: тип [XYZ] не может использоваться в этом контексте. Ошибка подтверждена
Я в своем уме на этом. Я иногда получаю сообщение об ошибке выше от моего веб-сервиса.Net 2.0 asmx. У меня есть правильный XmlInclude(), и он появляется только иногда - когда я перестраиваю и обновляю сайт, он может появиться, может и нет, ни рифмы, ни причины. Если я перемещаю некоторые из XmlInclude(), перестраиваю и нажимаю на изменения, ошибка обычно исчезает.
До начала процесса сборки, который конвертирует все в DLL, я использовал хороший метод развертывания ol xcopy. Тогда тоже произошла ошибка, но затем все, что мне нужно было сделать, это добавить пробел в файл, который определил все вызовы XmlInclude(), и IIS перекомпилировал бы, и ошибка исчезла.
Для чего это стоит, есть много определенных XmlInclude, около 100 или около того.
Есть идеи?
Вот фрагмент:
namespace Courses{
[Serializable]
[XmlInclude(typeof(UserToCourse)),
XmlInclude(typeof(UserToCourseCollection)),
// ...lots more....
XmlInclude(typeof(ReadOnlySearchResultsRecordset<UserToCourse, UserToCourseCollection>)),
XmlInclude(typeof(AllCoursesByTrainingProgramCollection)),
XmlInclude(typeof(StartupObject))]
public partial class ServiceCallResult{
//..snipped class def
}
}
Редактировать: Похоже, что перестановка XmlIncludes устраняет ошибку, но она может или не может вернуться в следующий раз, когда я перекомпилирую и повторно развернуть.
Правка № 2: ОК, еще несколько деталей. Принудительная переработка путем изменения файла web.config не решает проблему и не перезапускает IIS полностью. По какой-то причине мой журнал не записал должным образом, поэтому у меня пока нет трассировки стека.
На этот раз ошибка произошла для 2 конкретных методов. Я внес изменение в global.asax (чтобы попытаться исправить мою запись в журнале трассировки стека), перестроил и обновил, и один из двух методов начал работать. Затем я разделил класс с XmlInclude на него на 2 частичных класса, перестроил, обновил, и оба метода снова начали работать. Я не уверен, является ли это постоянным исправлением или нет в данный момент, потому что это настолько случайно; Я обновлю информацию о следующем цикле сборки снова.
Правка № 3: Определенно, это не постоянное исправление, и я все еще не подключен в нужное место для отслеживания полной трассировки стека (хотя мои другие журналы все работают нормально). Тьфу. Я обновлю снова в следующем раунде.
Правка № 4: Наконец, есть трассировка стека. Он не срабатывает ни в Visual Studio, ни в глобальном обработчике исключений в моем global.asax. Вот результаты, которые отображаются при вызове метода непосредственно из веб-браузера:
System.InvalidOperationException: There was an error generating the XML document. ---> System.InvalidOperationException: The type System.String[] may not be used in this context.
at System.Xml.Serialization.XmlSerializationWriter.WriteTypedPrimitive(String name, String ns, Object o, Boolean xsiType)
at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriter1.Write1_Object(String n, String ns, Object o, Boolean isNullable, Boolean needType)
at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriter1.Write119_ServiceCallResult(String n, String ns, ServiceCallResult o, Boolean isNullable, Boolean needType)
at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriter1.Write397_ServiceCallResult(Object o)
at Microsoft.Xml.Serialization.GeneratedAssembly.ServiceCallResultSerializer277.Serialize(Object objectToSerialize, XmlSerializationWriter writer)
at System.Xml.Serialization.XmlSerializer.Serialize(XmlWriter xmlWriter, Object o, XmlSerializerNamespaces namespaces, String encodingStyle, String id)
--- End of inner exception stack trace ---
at System.Xml.Serialization.XmlSerializer.Serialize(XmlWriter xmlWriter, Object o, XmlSerializerNamespaces namespaces, String encodingStyle, String id)
at System.Xml.Serialization.XmlSerializer.Serialize(TextWriter textWriter, Object o, XmlSerializerNamespaces namespaces)
at System.Xml.Serialization.XmlSerializer.Serialize(TextWriter textWriter, Object o)
at System.Web.Services.Protocols.XmlReturnWriter.Write(HttpResponse response, Stream outputStream, Object returnValue)
at System.Web.Services.Protocols.HttpServerProtocol.WriteReturns(Object[] returnValues, Stream outputStream)
at System.Web.Services.Protocols.WebServiceHandler.WriteReturns(Object[] returnValues)
at System.Web.Services.Protocols.WebServiceHandler.Invoke()
Редактировать № 5:
Это может быть признаком вышеуказанной ошибки, поэтому я не уверен, что она имеет отношение, но я все равно опубликую ее. Если я присоединяюсь к Managed Debug Assistants и обновляю кучу, я в итоге получаю:
Managed Debugging Assistant 'StreamWriterBufferedDataLost' has detected a problem in 'C:\Program Files\Common Files\Microsoft Shared\DevServer\9.0\WebDev.WebServer.EXE'.
Additional Information: A StreamWriter was not closed and all buffered data within that StreamWriter was not flushed to the underlying stream. (This was detected when the StreamWriter was finalized with data in its buffer.) A portion of the data was lost. Consider one of calling Close(), Flush(), setting the StreamWriter's AutoFlush property to true, or allocating the StreamWriter with a "using" statement. Stream type: System.Web.HttpResponseStream
File name: <unknown>
Allocated from:
at System.Environment.GetStackTrace(Exception e, Boolean needFileInfo)
at System.IO.StreamWriter.Init(Stream stream, Encoding encoding, Int32 bufferSize)
at System.IO.StreamWriter..ctor(Stream stream, Encoding encoding, Int32 bufferSize)
at System.IO.StreamWriter..ctor(Stream stream, Encoding encoding)
at System.Web.Services.Protocols.XmlReturnWriter.Write(HttpResponse response, Stream outputStream, Object returnValue)
at System.Web.Services.Protocols.HttpServerProtocol.WriteReturns(Object[] returnValues, Stream outputStream)
at System.Web.Services.Protocols.WebServiceHandler.WriteReturns(Object[] returnValues)
at System.Web.Services.Protocols.WebServiceHandler.Invoke()
at System.Web.Services.Protocols.WebServiceHandler.CoreProcessRequest()
at System.Web.Services.Protocols.SyncSessionlessHandler.ProcessRequest(HttpContext context)
at System.Web.Script.Services.ScriptHandlerFactory.HandlerWrapper.ProcessRequest(HttpContext context)
at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)
at System.Web.HttpApplication.ApplicationStepManager.ResumeSteps(Exception error)
at System.Web.HttpApplication.System.Web.IHttpAsyncHandler.BeginProcessRequest(HttpContext context, AsyncCallback cb, Object extraData)
at System.Web.HttpRuntime.ProcessRequestInternal(HttpWorkerRequest wr)
at System.Web.HttpRuntime.ProcessRequestNoDemand(HttpWorkerRequest wr)
at System.Web.HttpRuntime.ProcessRequest(HttpWorkerRequest wr)
at Microsoft.VisualStudio.WebHost.Request.Process()
at Microsoft.VisualStudio.WebHost.Host.ProcessRequest(Connection conn)
Я не уверен, что это связано... может быть просто поток ошибок.
Изменить № 6:
ОК, больше информации. Я использовал пост в блоге Скотта Хансельмана, чтобы войти в созданную сборку. Оказывается, что, несмотря на XmlInclude, сгенерированная сборка НЕ имеет ссылки на тип, поэтому это определенно ошибка в.NET. Я пытаюсь отследить, что это вызывает, но что-то в том, что генерирует выходные сборки (sgen?), Терпит неудачу.
Редактировать № 7:
К вашему сведению, я отправил отчет об ошибке в MS:
https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=523253
2 ответа
Мое лучшее предположение (и это предположение) состоит в том, что касание файла - красная сельдь. Я думаю, что более вероятно, что любая перекомпиляция прояснит это. Например, вы можете прикоснуться к web.config, чтобы заставить recycle подтвердить или опровергнуть мое предположение, когда это произойдет.
Я подозреваю, что причина в том, что полученная вами ошибка связана с проблемой сериализации. Сериализатор XML заблуждается, думая, что он не может сериализовать один из ваших типов. Поскольку вы исключили множество распространенных подозрений, таких как массивы объектов или включение других типов, которые по своей природе не сериализуемы, я подозреваю, что виновато состояние гонки компиляции, такое как круговая ссылка между двумя вашими сборками. Этот конкретный случай будет выяснен второй компиляцией.
Примечание. Хорошим инструментом для обнаружения циклических ссылок является NDepend.
Если это не циклическая ссылка, используете ли вы какой-либо код, используете ли вы каких-либо провайдеров сборки или используете отражение для загрузки каких-либо сборок в ваше приложение или чего-то еще, что может быть даже немного экзотическим?
Редактировать:
Исходя из вашего комментария, вы не делаете ничего экзотического. Поэтому, пожалуйста, проверьте наличие циклических ссылок и (только что подумал) конфликтующих зависимостей между вашими сборками. Например, SubSonic ссылается на несколько сборок, и если вы ссылаетесь на одну из этих сборок другой версии, она может объяснить, как она работает один раз, а в другой раз - с тем же кодом.
ОК, у меня есть решение, которое работает, хотя я до сих пор не уверен, почему. Это определенно ошибка в сгенерированной сборке прокси. Я обнаружил, что сгенерированная сборка иногда просто пропускает некоторые типы, включенные в XmlInclude. Как ни странно, это были определенные типы, хотя я не могу найти образец, почему эти, а не другие.
Решение состояло в том, чтобы создать частичное определение класса (даже в том же файле!), Которое содержало XmlInclude только для тех конкретных типов, которые постоянно вызывали проблемы. С тех пор я вообще не видел ошибки.
Определенно ошибка где-то в генераторе, хотя что это вызывает, я не знаю. Надеюсь, это поможет кому-то еще в будущем.
РЕДАКТИРОВАТЬ Я верю, что я подтвердил, что вызвало проблему. У меня была ссылка на SharpZipLib, созданную для.NET Framework v1.1, в моем проекте.NET 2.0. Когда я собрал app_code.dll, он добавил ссылку на mscorlib 1.0.5. Очевидно, этой дополнительной ссылки было достаточно, чтобы sgen неправильно генерировал временные библиотеки DLL, используемые при вызове веб-службы. Итак, если у вас возникла проблема... загрузите все ссылочные сборки в ILDASM, дважды щелкните манифест и убедитесь, что ни одна из них не ссылается на.NET 1.1. Если они это сделают... вы прокляты.
По-видимому, это на самом деле не решило проблему, так как проблема все еще существует, просто с ошибкой другого типа.