У меня есть некоторый код ввода-вывода, который читает поток в try..catch. Он перехватывает IOException и вызывает System.Runtime.InteropServices.Marshal.GetHRForException ()
в рамках улова, в попытке предпринять различные действия на основе HResult. Примерно так:
try
{
stream.Read(...);
}
catch (IOException ioexc1)
{
uint hr = (uint) Marshal.GetHRForException(ioexc1);
if (hr == ...)
do_one_thing();
else
do_another();
}
Сборка подписана и помечена AllowPartiallyTrustedCallersAttribute .
Но, запустив этот код в ASP.NET с trust = "medium", я получаю следующее исключение:
Request for the permission of type 'System.Security.Permissions.SecurityPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' failed.
Пара вопросов:
- Я думаю, что исключение происходит, потому что GetHRForException вызывает неуправляемый код, что недопустимо при среднем доверии. Правильно?
- Это исключение выдается не во время выполнения GetHRForException, а во время выполнения метода JIT - правильно? (Трассировка стека показывает мой метод, но я на 99% уверен, что исключение ввода-вывода не произошло)
- Если это так, могу ли я изменить поведение в среде с частичным доверием, чтобы я не вызывал GetHRForException (неуправляемый код) там, где это не разрешено? Другими словами, как я могу позволить JIT успешно выполняться во время компиляции, а также оценивать во время выполнения, должен ли код вызывать GetHRForException ()? Примерно так:
catch (IOException ioexc1)
{
if (!OkToCallUnmanaged())
throw ioexc1;
uint hr = (uint) Marshal.GetHRForException(ioexc1);
if (hr == ...)
do_one_thing();
else
do_another();
}
Я думаю, что есть механизм времени выполнения для проверки наличия разрешений, но они не смогли его найти.
РЕДАКТИРОВАТЬ : эта статья блога ответ? ShawnFa из Microsoft говорит, что вы не можете сделать попытку ... поймать (SecurityException) вокруг метода, защищенного LinkDemand. Если MethodA () вызывает MethodB (), а MethodB () помечается LinkDemand для полного доверия, то LinkDemand проверяется с помощью MethodA Jit'ed. Поэтому, чтобы избежать исключения SecurityException, мне нужно извлечь Marshal.GetHRForException в отдельный метод. Это верно?
Применительно к моему коду, MethodA () может быть кодом, который вызывает Read, а затем в перехвате пытается вызвать GetHRForException (). GetHRForException - это MethodB (). LinkDemand оценивается, когда MethodA () является JIT'd. (Этот LinkDemand не выполняется в моем сценарии ASP.NET со средним уровнем доверия). Если я переместлю GetHRForException в новый метод, MethodC (), и условно вызову MethodC () только после императивного разрешения. Функция Demand () теоретически должна быть в состоянии избежать исключения SecurityException во время JIT, поскольку MethodC () JIT'd только после разрешения. Demain () успешно.