internal object Deserialize(HeaderHandler handler, ISerParser serParser) { if (serParser == null) { throw new ArgumentNullException("serParser", string.Format(CultureInfo.CurrentCulture, SoapUtil.GetResourceString("ArgumentNull_WithParamName"), new object[] { serParser })); } this.deserializationSecurityException = null; try { serializationPermission.Demand(); } catch (Exception exception) { this.deserializationSecurityException = exception; } this.handler = handler; this.isTopObjectSecondPass = false; this.isHeaderHandlerCalled = false; if (handler != null) { this.IsFakeTopObject = true; } this.m_idGenerator = new ObjectIDGenerator(); this.m_objectManager = this.GetObjectManager(); this.serObjectInfoInit = new SerObjectInfoInit(); this.objectIdTable.Clear(); this.objectIds = 0L; serParser.Run(); if (handler != null) { this.m_objectManager.DoFixups(); if (this.handlerObject == null) { this.handlerObject = handler(this.newheaders); } if ((this.soapFaultId > 0L) && (this.handlerObject != null)) { this.topStack = new SerStack("Top ParseRecords"); ParseRecord record = new ParseRecord { PRparseTypeEnum = InternalParseTypeE.Object, PRobjectPositionEnum = InternalObjectPositionE.Top, PRparseStateEnum = InternalParseStateE.Object, PRname = "Response" }; this.topStack.Push(record); record = new ParseRecord { PRparseTypeEnum = InternalParseTypeE.Member, PRobjectPositionEnum = InternalObjectPositionE.Child, PRmemberTypeEnum = InternalMemberTypeE.Field, PRmemberValueEnum = InternalMemberValueE.Reference, PRparseStateEnum = InternalParseStateE.Member, PRname = "__fault", PRidRef = this.soapFaultId }; this.topStack.Push(record); record = new ParseRecord { PRparseTypeEnum = InternalParseTypeE.ObjectEnd, PRobjectPositionEnum = InternalObjectPositionE.Top, PRparseStateEnum = InternalParseStateE.Object, PRname = "Response" }; this.topStack.Push(record); this.isTopObjectResolved = false; } } if (!this.isTopObjectResolved) { this.isTopObjectSecondPass = true; this.topStack.Reverse(); int num = this.topStack.Count(); ParseRecord pr = null; for (int i = 0; i < num; i++) { pr = (ParseRecord) this.topStack.Pop(); this.Parse(pr); } } this.m_objectManager.DoFixups(); if (this.topObject == null) { throw new SerializationException(SoapUtil.GetResourceString("Serialization_TopObject")); } if (this.HasSurrogate(this.topObject.GetType()) && (this.topId != 0L)) { this.topObject = this.m_objectManager.GetObject(this.topId); } if (this.topObject is IObjectReference) { this.topObject = ((IObjectReference) this.topObject).GetRealObject(this.m_context); } this.m_objectManager.RaiseDeserializationEvent(); if ((this.formatterEnums.FEtopObject != null) && (this.topObject is InternalSoapMessage)) { InternalSoapMessage topObject = (InternalSoapMessage) this.topObject; ISoapMessage fEtopObject = this.formatterEnums.FEtopObject; fEtopObject.MethodName = topObject.methodName; fEtopObject.XmlNameSpace = topObject.xmlNameSpace; fEtopObject.ParamNames = topObject.paramNames; fEtopObject.ParamValues = topObject.paramValues; fEtopObject.Headers = this.headers; this.topObject = fEtopObject; this.isTopObjectResolved = true; } return this.topObject; }
// New object encountered in stream private void ParseObject(ParseRecord pr) { InternalST.Soap( this, "ParseObject Entry "); if (pr.PRobjectPositionEnum == InternalObjectPositionE.Top) topId = pr.PRobjectId; if (pr.PRparseTypeEnum == InternalParseTypeE.Object) { InternalST.Soap( this, "ParseObject Push "+pr.PRname); stack.Push(pr); // Nested objects member names are already on stack } if (pr.PRobjectTypeEnum == InternalObjectTypeE.Array) { ParseArray(pr); InternalST.Soap( this, "ParseObject Exit, ParseArray "); return; } if ((pr.PRdtType == null) && !IsFakeTopObject) throw new SerializationException(String.Format(SoapUtil.GetResourceString("Serialization_TopObjectInstantiate"),pr.PRname)); if (pr.PRobjectPositionEnum == InternalObjectPositionE.Top && IsFakeTopObject && pr.PRdtType != Converter.typeofSoapFault) { // Soap fake top object if (handler != null) { // Handler object will supply real top object InternalST.Soap( this, "ParseObject FakeTopObject with handlerObject "); // Now know the method name, can call header handler //Create header for method name if (!isHeaderHandlerCalled) { newheaders = null; isHeaderHandlerCalled = true; if (headers == null) { newheaders = new Header[1]; } else { newheaders = new Header[headers.Length+1]; Array.Copy(headers, 0, newheaders, 1, headers.Length); } Header methodNameHeader = new Header("__methodName", pr.PRname, false, pr.PRnameXmlKey); newheaders[0] = methodNameHeader; InternalST.Soap( this, "Deserialize Before Delegate Invoke "); handlerObject = handler(newheaders); InternalST.Soap( this, "Deserialize after Delegate Invoke"); InternalST.Soap( this, "Deserialize delgate object ",((handlerObject == null)?"null":handlerObject)); } if (isHeaderHandlerCalled) { // Handler object has supplied the real object for the fake object // which is on top of the stack pr.PRnewObj = handlerObject; pr.PRdtType = handlerObject.GetType(); CheckSecurity(pr); if (pr.PRnewObj is IFieldInfo) { IFieldInfo fi = (IFieldInfo)pr.PRnewObj; if ((fi.FieldTypes != null) && (fi.FieldTypes.Length > 0)) { pr.PRobjectInfo = CreateReadObjectInfo(pr.PRdtType, fi.FieldNames, fi.FieldTypes, pr.PRassemblyName); } } } else { // Handler object has not yet been asked for the real object // Stack the parse record until the second pass isTopObjectResolved = false; topStack = new SerStack("Top ParseRecords"); InternalST.Soap( this, "ParseObject Handler Push "+pr.PRname); topStack.Push(pr.Copy()); return; } } else if (formatterEnums.FEtopObject != null) { // SoapMessage will be used as the real object InternalST.Soap( this, "ParseObject FakeTopObject with SoapMessage "); if (isTopObjectSecondPass) { // This creates a the SoapMessage object as the real object, at this point it is an unitialized object. pr.PRnewObj = new InternalSoapMessage(); pr.PRdtType = typeof(InternalSoapMessage); CheckSecurity(pr); if (formatterEnums.FEtopObject != null) { ISoapMessage soapMessage = (ISoapMessage)formatterEnums.FEtopObject; pr.PRobjectInfo = CreateReadObjectInfo(pr.PRdtType, soapMessage.ParamNames, soapMessage.ParamTypes, pr.PRassemblyName); } } else { // Stack the parse record until the second pass isTopObjectResolved = false; topStack = new SerStack("Top ParseRecords"); topStack.Push(pr.Copy()); return; } } } else if (pr.PRdtType == Converter.typeofString) { // String as a top level object if (pr.PRvalue != null) { pr.PRnewObj = pr.PRvalue; if (pr.PRobjectPositionEnum == InternalObjectPositionE.Top) { InternalST.Soap( this, "ParseObject String as top level, Top Object Resolved"); isTopObjectResolved = true; topObject = pr.PRnewObj; //stack.Pop(); return; } else { InternalST.Soap( this, "ParseObject String as an object"); stack.Pop(); RegisterObject(pr.PRnewObj, pr, (ParseRecord)stack.Peek()); return; } } else { // xml Doesn't have the value until later return; } } else { if (pr.PRdtType == null) { ParseRecord objectPr = (ParseRecord)stack.Peek(); if (objectPr.PRdtType == Converter.typeofSoapFault) { InternalST.Soap( this, "ParseObject unknown SoapFault detail"); throw new ServerException(String.Format(SoapUtil.GetResourceString("Serialization_SoapFault"),faultString)); } throw new SerializationException(String.Format(SoapUtil.GetResourceString("Serialization_TypeElement"),pr.PRname)); } pr.PRnewObj = FormatterServices.GetUninitializedObject(pr.PRdtType); CheckSecurity(pr); } if (pr.PRnewObj == null) throw new SerializationException(String.Format(SoapUtil.GetResourceString("Serialization_TopObjectInstantiate"),pr.PRdtType)); long genId = pr.PRobjectId; if (genId < 1) pr.PRobjectId = GetId("GenId-"+objectIds); if (IsFakeTopObject && pr.PRobjectPositionEnum == InternalObjectPositionE.Top) { InternalST.Soap( this, "ParseObject fake Top object resolved ",pr.PRnewObj); isTopObjectResolved = true; topObject = pr.PRnewObj; } if (pr.PRobjectInfo == null) pr.PRobjectInfo = CreateReadObjectInfo(pr.PRdtType, pr.PRassemblyName); pr.PRobjectInfo.obj = pr.PRnewObj; if (IsFakeTopObject && pr.PRobjectPositionEnum == InternalObjectPositionE.Top) { InternalST.Soap( this, "ParseObject AddValue to fake object ",pr.PRobjectInfo.obj); // Add the methodName to top object, either InternalSoapMessage or object returned by handler pr.PRobjectInfo.AddValue("__methodName", pr.PRname); pr.PRobjectInfo.AddValue("__keyToNamespaceTable", soapHandler.keyToNamespaceTable); pr.PRobjectInfo.AddValue("__paramNameList", pr.PRobjectInfo.SetFakeObject()); if (formatterEnums.FEtopObject != null) pr.PRobjectInfo.AddValue("__xmlNameSpace", pr.PRxmlNameSpace); } InternalST.Soap( this, "ParseObject Exit "); }
private void ParseObject(ParseRecord pr) { if (pr.PRobjectPositionEnum == InternalObjectPositionE.Top) { this.topId = pr.PRobjectId; } if (pr.PRparseTypeEnum == InternalParseTypeE.Object) { this.stack.Push(pr); } if (pr.PRobjectTypeEnum == InternalObjectTypeE.Array) { this.ParseArray(pr); } else { if ((pr.PRdtType == null) && !this.IsFakeTopObject) { throw new SerializationException(string.Format(CultureInfo.CurrentCulture, SoapUtil.GetResourceString("Serialization_TopObjectInstantiate"), new object[] { pr.PRname })); } if (((pr.PRobjectPositionEnum == InternalObjectPositionE.Top) && this.IsFakeTopObject) && (pr.PRdtType != Converter.typeofSoapFault)) { if (this.handler == null) { if (this.formatterEnums.FEtopObject != null) { if (!this.isTopObjectSecondPass) { this.isTopObjectResolved = false; this.topStack = new SerStack("Top ParseRecords"); this.topStack.Push(pr.Copy()); return; } pr.PRnewObj = new InternalSoapMessage(); pr.PRdtType = typeof(InternalSoapMessage); this.CheckSecurity(pr); if (this.formatterEnums.FEtopObject != null) { ISoapMessage fEtopObject = this.formatterEnums.FEtopObject; pr.PRobjectInfo = this.CreateReadObjectInfo(pr.PRdtType, fEtopObject.ParamNames, fEtopObject.ParamTypes, pr.PRassemblyName); } } } else { if (!this.isHeaderHandlerCalled) { this.newheaders = null; this.isHeaderHandlerCalled = true; if (this.headers == null) { this.newheaders = new Header[1]; } else { this.newheaders = new Header[this.headers.Length + 1]; Array.Copy(this.headers, 0, this.newheaders, 1, this.headers.Length); } Header header = new Header("__methodName", pr.PRname, false, pr.PRnameXmlKey); this.newheaders[0] = header; this.handlerObject = this.handler(this.newheaders); } if (!this.isHeaderHandlerCalled) { this.isTopObjectResolved = false; this.topStack = new SerStack("Top ParseRecords"); this.topStack.Push(pr.Copy()); return; } pr.PRnewObj = this.handlerObject; pr.PRdtType = this.handlerObject.GetType(); this.CheckSecurity(pr); if (pr.PRnewObj is IFieldInfo) { IFieldInfo pRnewObj = (IFieldInfo) pr.PRnewObj; if ((pRnewObj.FieldTypes != null) && (pRnewObj.FieldTypes.Length > 0)) { pr.PRobjectInfo = this.CreateReadObjectInfo(pr.PRdtType, pRnewObj.FieldNames, pRnewObj.FieldTypes, pr.PRassemblyName); } } } } else { if (pr.PRdtType == Converter.typeofString) { if (pr.PRvalue != null) { pr.PRnewObj = pr.PRvalue; if (pr.PRobjectPositionEnum == InternalObjectPositionE.Top) { this.isTopObjectResolved = true; this.topObject = pr.PRnewObj; return; } this.stack.Pop(); this.RegisterObject(pr.PRnewObj, pr, (ParseRecord) this.stack.Peek()); } return; } if (pr.PRdtType == null) { ParseRecord record = (ParseRecord) this.stack.Peek(); if (record.PRdtType == Converter.typeofSoapFault) { throw new ServerException(string.Format(CultureInfo.CurrentCulture, SoapUtil.GetResourceString("Serialization_SoapFault"), new object[] { this.faultString })); } throw new SerializationException(string.Format(CultureInfo.CurrentCulture, SoapUtil.GetResourceString("Serialization_TypeElement"), new object[] { pr.PRname })); } this.CheckSerializable(pr.PRdtType); if (this.IsRemoting && (this.formatterEnums.FEsecurityLevel != TypeFilterLevel.Full)) { pr.PRnewObj = FormatterServices.GetSafeUninitializedObject(pr.PRdtType); } else { pr.PRnewObj = FormatterServices.GetUninitializedObject(pr.PRdtType); } this.CheckSecurity(pr); this.m_objectManager.RaiseOnDeserializingEvent(pr.PRnewObj); } if (pr.PRnewObj == null) { throw new SerializationException(string.Format(CultureInfo.CurrentCulture, SoapUtil.GetResourceString("Serialization_TopObjectInstantiate"), new object[] { pr.PRdtType })); } if (pr.PRobjectId < 1L) { pr.PRobjectId = this.GetId("GenId-" + this.objectIds); } if (this.IsFakeTopObject && (pr.PRobjectPositionEnum == InternalObjectPositionE.Top)) { this.isTopObjectResolved = true; this.topObject = pr.PRnewObj; } if (pr.PRobjectInfo == null) { pr.PRobjectInfo = this.CreateReadObjectInfo(pr.PRdtType, pr.PRassemblyName); } pr.PRobjectInfo.obj = pr.PRnewObj; if (this.IsFakeTopObject && (pr.PRobjectPositionEnum == InternalObjectPositionE.Top)) { pr.PRobjectInfo.AddValue("__methodName", pr.PRname); pr.PRobjectInfo.AddValue("__keyToNamespaceTable", this.soapHandler.keyToNamespaceTable); pr.PRobjectInfo.AddValue("__paramNameList", pr.PRobjectInfo.SetFakeObject()); if (this.formatterEnums.FEtopObject != null) { pr.PRobjectInfo.AddValue("__xmlNameSpace", pr.PRxmlNameSpace); } } } }
// Deserialize the stream into an object graph. internal Object Deserialize(HeaderHandler handler, ISerParser serParser) { InternalST.Soap( this, "Deserialize Entry handler", handler); if (serParser == null) throw new ArgumentNullException("serParser", String.Format(SoapUtil.GetResourceString("ArgumentNull_WithParamName"), serParser)); deserializationSecurityException = null; try { serializationPermission.Demand(); } catch(Exception e ) { deserializationSecurityException = e; } this.handler = handler; isTopObjectSecondPass = false; isHeaderHandlerCalled = false; if (handler != null) IsFakeTopObject = true; m_idGenerator = new ObjectIDGenerator(); m_objectManager = GetObjectManager(); serObjectInfoInit = new SerObjectInfoInit(); objectIdTable.Clear(); objectIds = 0; // Will call back to ParseObject, ParseHeader for each object found serParser.Run(); if (handler != null) { InternalST.Soap( this, "Deserialize Fixup Before Delegate Invoke"); m_objectManager.DoFixups(); // Fixup for headers // Header handler isn't invoked until method name is known from body fake record // Except for SoapFault, in which case it is invoked below if (handlerObject == null) { InternalST.Soap( this, "Deserialize Before SoapFault Delegate Invoke "); handlerObject = handler(newheaders); InternalST.Soap( this, "Deserialize after SoapFault Delegate Invoke"); } // SoapFault creation Create a fake Pr for the handlerObject to use. // Create a member for the fake pr with name __fault; if ((soapFaultId > 0) && (handlerObject != null)) { InternalST.Soap( this, "Deserialize SoapFault "); topStack = new SerStack("Top ParseRecords"); ParseRecord pr = new ParseRecord(); pr.PRparseTypeEnum = InternalParseTypeE.Object; pr.PRobjectPositionEnum = InternalObjectPositionE.Top; pr.PRparseStateEnum = InternalParseStateE.Object; pr.PRname = "Response"; topStack.Push(pr); pr = new ParseRecord(); pr.PRparseTypeEnum = InternalParseTypeE.Member; pr.PRobjectPositionEnum = InternalObjectPositionE.Child; pr.PRmemberTypeEnum = InternalMemberTypeE.Field; pr.PRmemberValueEnum = InternalMemberValueE.Reference; pr.PRparseStateEnum = InternalParseStateE.Member; pr.PRname = "__fault"; pr.PRidRef = soapFaultId; topStack.Push(pr); pr = new ParseRecord(); pr.PRparseTypeEnum = InternalParseTypeE.ObjectEnd; pr.PRobjectPositionEnum = InternalObjectPositionE.Top; pr.PRparseStateEnum = InternalParseStateE.Object; pr.PRname = "Response"; topStack.Push(pr); isTopObjectResolved = false; } } // Resolve fake top object if necessary if (!isTopObjectResolved) { //resolve top object InternalST.Soap( this, "Deserialize TopObject Second Pass"); isTopObjectSecondPass = true; topStack.Reverse(); // The top of the stack now contains the fake record // When it is Parsed, the handler object will be substituted // for it in ParseObject. int topStackLength = topStack.Count(); ParseRecord pr = null; for (int i=0; i<topStackLength; i++) { pr = (ParseRecord)topStack.Pop(); Parse(pr); } } InternalST.Soap( this, "Deserialize Finished Parsing DoFixups"); m_objectManager.DoFixups(); if (topObject == null) throw new SerializationException(SoapUtil.GetResourceString("Serialization_TopObject")); if (topObject is IObjectReference) { topObject = ((IObjectReference)topObject).GetRealObject(m_context); } InternalST.Soap( this, "Deserialize Exit ",topObject); m_objectManager.RaiseDeserializationEvent(); if ((formatterEnums.FEtopObject != null) && (topObject is InternalSoapMessage)) { // Convert InternalSoapMessage to SoapMessage InternalST.Soap( this, "Deserialize SoapMessage Entry "); InternalSoapMessage ismc = (InternalSoapMessage)topObject; ISoapMessage smc = (ISoapMessage)formatterEnums.FEtopObject; smc.MethodName = ismc.methodName; smc.XmlNameSpace = ismc.xmlNameSpace; smc.ParamNames = ismc.paramNames; smc.ParamValues = ismc.paramValues; smc.Headers = headers; topObject = smc; isTopObjectResolved = true; InternalST.Soap( this, "Deserialize SoapMessage Exit topObject ",topObject," method name ",smc.MethodName); } return topObject; }