ISafeSerializationData 인터페이스
정의
중요
일부 정보는 릴리스되기 전에 상당 부분 수정될 수 있는 시험판 제품과 관련이 있습니다. Microsoft는 여기에 제공된 정보에 대해 어떠한 명시적이거나 묵시적인 보증도 하지 않습니다.
보안 투명 코드에서 사용자 지정 예외 데이터의 serialization을 사용할 수 있습니다.
public interface class ISafeSerializationData
public interface ISafeSerializationData
type ISafeSerializationData = interface
Public Interface ISafeSerializationData
예제
다음 예제에는 직렬화된 사용자 지정 데이터를 저장하는 데 사용되는 인터페이스의 ISafeSerializationData 구현이 포함되어 있습니다.
using System;
using System.Runtime.Serialization.Formatters.Binary;
using System.Runtime.Serialization;
using System.IO;
using System.Runtime.Serialization.Formatters.Soap;
using System.Security;
// [assembly: SecurityCritical(SecurityCriticalScope.Everything)]
// Using the SecurityCriticalAttribute prohibits usage of the
// ISafeSerializationData interface.
[assembly: AllowPartiallyTrustedCallers]
namespace ISafeSerializationDataExample
{
class Test
{
public static void Main()
{
try
{
// This code forces a division by 0 and catches the
// resulting exception.
try
{
int zero = 0;
int ecks = 1 / zero;
}
catch (Exception ex)
{
// Create a new exception to throw.
NewException newExcept = new NewException("Divided by", 0);
// This FileStream is used for the serialization.
FileStream fs =
new FileStream("NewException.dat",
FileMode.Create);
try
{
// Serialize the exception.
BinaryFormatter formatter = new BinaryFormatter();
formatter.Serialize(fs, newExcept);
// Rewind the stream and deserialize the exception.
fs.Position = 0;
NewException deserExcept =
(NewException)formatter.Deserialize(fs);
Console.WriteLine(
"Forced a division by 0, caught the resulting exception, \n" +
"and created a derived exception with custom data. \n" +
"Serialized the exception and deserialized it:\n");
Console.WriteLine("StringData: {0}", deserExcept.StringData);
Console.WriteLine("intData: {0}", deserExcept.IntData);
}
catch (SerializationException se)
{
Console.WriteLine("Failed to serialize: {0}",
se.ToString());
}
finally
{
fs.Close();
Console.ReadLine();
}
}
}
catch (NewException ex)
{
Console.WriteLine("StringData: {0}", ex.StringData);
Console.WriteLine("IntData: {0}", ex.IntData);
}
}
}
[Serializable]
public class NewException : Exception
{
// Because we don't want the exception state to be serialized normally,
// we take care of that in the constructor.
[NonSerialized]
private NewExceptionState m_state = new NewExceptionState();
public NewException(string stringData, int intData)
{
// Instance data is stored directly in the exception state object.
m_state.StringData = stringData;
m_state.IntData = intData;
// In response to SerializeObjectState, we need to provide
// any state to serialize with the exception. In this
// case, since our state is already stored in an
// ISafeSerializationData implementation, we can
// just provide that.
SerializeObjectState += delegate(object exception,
SafeSerializationEventArgs eventArgs)
{
eventArgs.AddSerializedState(m_state);
};
// An alternate implementation would be to store the state
// as local member variables, and in response to this
// method create a new instance of an ISafeSerializationData
// object and populate it with the local state here before
// passing it through to AddSerializedState.
}
// There is no need to supply a deserialization constructor
// (with SerializationInfo and StreamingContext parameters),
// and no need to supply a GetObjectData implementation.
// Data access is through the state object (m_State).
public string StringData
{
get { return m_state.StringData; }
}
public int IntData
{
get { return m_state.IntData; }
}
// Implement the ISafeSerializationData interface
// to contain custom exception data in a partially trusted
// assembly. Use this interface to replace the
// Exception.GetObjectData method,
// which is now marked with the SecurityCriticalAttribute.
[Serializable]
private struct NewExceptionState : ISafeSerializationData
{
private string m_stringData;
private int m_intData;
public string StringData
{
get { return m_stringData; }
set { m_stringData = value; }
}
public int IntData
{
get { return m_intData; }
set { m_intData = value; }
}
// This method is called when deserialization of the
// exception is complete.
void ISafeSerializationData.CompleteDeserialization
(object obj)
{
// Since the exception simply contains an instance of
// the exception state object, we can repopulate it
// here by just setting its instance field to be equal
// to this deserialized state instance.
NewException exception = obj as NewException;
exception.m_state = this;
}
}
}
}
Imports System.Runtime.Serialization.Formatters.Binary
Imports System.Runtime.Serialization
Imports System.IO
Imports System.Runtime.Serialization.Formatters.Soap
Imports System.Security
' Imports System.Security.Permissions
'[assembly: SecurityCritical(SecurityCriticalScope.Everything)]
' Using the SecurityCriticalAttribute prohibits usage of the
' ISafeSerializationData interface.
<Assembly: AllowPartiallyTrustedCallers()>
Namespace ISafeSerializationDataExample
Class SerializationDemo
Shared Sub Main()
' This code forces a division by 0 and catches the
' resulting exception.
Try
Dim zero As Integer = 0
Dim ecks As Integer = 1 / zero
Catch ex As Exception
' Create a new exception to throw again.
Dim newExcept As New NewException("Divided by.", 0)
Console.WriteLine(
"Forced a division by 0, caught the resulting exception, \n" & _
"and created a derived exception with custom data:\n")
Console.WriteLine("StringData: {0}", newExcept.StringData)
Console.WriteLine("intData: {0}", newExcept.IntData)
' This FileStream is used for the serialization.
Dim fs As New FileStream("NewException.dat", _
FileMode.Create)
Try
' Serialize the derived exception.
Dim Formatter As New BinaryFormatter()
Formatter.Serialize(fs, newExcept)
' Rewind the stream and deserialize the exception.
fs.Position = 0
Dim deserExcept As NewException = _
CType(Formatter.Deserialize(fs), NewException)
Catch se As SerializationException
Console.WriteLine("Failed to serialize: {0}", _
se.ToString())
Catch NewEx As NewException
Console.WriteLine("StringData: {0}", _
NewEx.StringData)
Console.WriteLine("IntData: {0}", _
NewEx.IntData)
Finally
fs.Close()
Console.ReadLine()
End Try
End Try
End Sub
End Class
<Serializable()> Public Class NewException
Inherits Exception
<NonSerialized()> Private m_state As NewExceptionState = New NewExceptionState()
Public Sub New(ByVal stringData As String, ByVal intData As Integer)
' Instance data is stored directly in the exception
' state(Object.
m_state.StringData = stringData
m_state.IntData = intData
' In response to SerializeObjectState, we need to provide
' any state to serialize with the exception. In this
' case, since our state is already stored in an
' ISafeSerializationData implementation, we can
' just provide that.
' An alternate implementation would be to store the state
' as local member variables, and in response to this
' method create a new instance of an ISafeSerializationData
' object and populate it with the local state here before
' passing it through to AddSerializedState.
AddHandler SerializeObjectState, _
Sub(exception As Object, _
eventArgs As SafeSerializationEventArgs)
eventArgs.AddSerializedState(m_state)
End Sub
End Sub
' Because we don't want the exception state to be serialized
' normally, we take care of that in the constructor.
' Data access is through the state object, rather than locally.
Public Property StringData As String
Get
Return m_state.StringData
End Get
Set(ByVal value As String)
m_state.StringData = value
End Set
End Property
Public Property IntData As Integer
Get
Return m_state.IntData
End Get
Set(ByVal value As Integer)
m_state.IntData = value
End Set
End Property
'There is no need to supply a deserialization constructor
'(with SerializationInfo and StreamingContext parameters),
'and no need to supply a GetObjectData implementation.
'Implement the ISafeSerializationData interface to serialize
'custom exception data in a partially trusted assembly.
'Use this interface to replace the Exception.GetObjectData
'method, which is now marked with the SecurityCriticalAttribute.
<Serializable()> Private Structure NewExceptionState
Implements ISafeSerializationData
Private m_stringData As String
Private m_intData As Integer
' This method is called when deserialization of the
' exception is complete.
Sub CompleteDeserialization(ByVal obj As Object) _
Implements ISafeSerializationData.CompleteDeserialization
' Since the exception simply contains an instance
' of the exception state object, we can repopulate it
' here by just setting its instance field
' to be equal to this deserialized state instance.
Dim exception As NewException = _
CType(obj, NewException)
exception.m_state = Me
End Sub
Public Property StringData As String
Get
Return m_stringData
End Get
Set(ByVal value As String)
m_stringData = value
End Set
End Property
Public Property IntData As Integer
Get
Return m_intData
End Get
Set(ByVal value As Integer)
m_intData = value
End Set
End Property
End Structure
End Class
End Namespace
설명
이전 버전의 to.NET Framework 4.0에서는 이 메서드를 사용하여 GetObjectData 보안 투명 코드에서 사용자 지정 사용자 데이터를 serialization했습니다. .NET Framework 4.0부터 해당 메서드는 보안 투명 코드에서 실행을 방지하는 특성으로 SecurityCriticalAttribute 표시됩니다. 이 조건을 해결하려면 아래 예제와 같이 인터페이스를 ISafeSerializationData 구현하고 사용자 지정 데이터를 추가합니다.
이 CompleteDeserialization 메서드는 serialization 후에 호출되고 사용자 지정 데이터를 복원하는 데 사용됩니다 SafeSerializationEventArgs .
메서드
CompleteDeserialization(Object) |
이 메서드는 인스턴스가 역직렬화될 때 호출됩니다. |