[*]Сериализация с использованием Runtime.Serialization приводит к тому, что объект ArrayOf будет введен, если какие-либо коллекции ожидается в качестве параметров веб-методов.
public void Foo(int[] ids) ==> public void Foo(int[] ids) System.ServiceModel
публичный void Foo(int[] ids) ==> public void Foo(ArrayOfInt ids) System.Runtime.Serialization
[*]Выбранный механизм сериализации зависит от параметра, полученного из типа абстрактного класса (или являющегося им).
public void Bar(int[] ids) ==> Используется System.Runtime.Serialization.
public void Bar(DerivedFromAbstractClass baz, int[] ids) ==> System.ServiceModel > используется.
public abstract class Foo { }
///
/// Summary description for WebService1
///
[System.Web.Services.WebService(Namespace = "http://tempuri.org/")]
[System.Web.Services.WebServiceBinding(ConformsTo = System.Web.Services.WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
// To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line.
// [System.Web.Script.Services.ScriptService]
public class WebService1 : System.Web.Services.WebService
{
[System.Web.Services.WebMethod]
public void HelloWorld(Foo foo, int[] ids)
{
}
}
Вот как выглядит мой файл .asmx. Обратите внимание на типы параметров, ожидаемые hello world. Теперь я создаю ссылку на сервис:
namespace CableSolve.Web.Api.Tests.ServiceReference2 {
using System.Runtime.Serialization;
using System;
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "4.0.0.0")]
[System.Runtime.Serialization.CollectionDataContractAttribute(Name="ArrayOfInt", Namespace="http://tempuri.org/", ItemName="int")]
[System.SerializableAttribute()]
public class ArrayOfInt : System.Collections.Generic.List {
}
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
[System.ServiceModel.ServiceContractAttribute(ConfigurationName="ServiceReference2.WebService1Soap")]
public interface WebService1Soap {
// CODEGEN: Generating message contract since element name ids from namespace http://tempuri.org/ is not marked nillable
[System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/HelloWorld", ReplyAction="*")]
CableSolve.Web.Api.Tests.ServiceReference2.HelloWorldResponse HelloWorld(CableSolve.Web.Api.Tests.ServiceReference2.HelloWorldRequest request);
}
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
[System.ServiceModel.MessageContractAttribute(IsWrapped=false)]
public partial class HelloWorldRequest {
[System.ServiceModel.MessageBodyMemberAttribute(Name="HelloWorld", Namespace="http://tempuri.org/", Order=0)]
public CableSolve.Web.Api.Tests.ServiceReference2.HelloWorldRequestBody Body;
public HelloWorldRequest() {
}
public HelloWorldRequest(CableSolve.Web.Api.Tests.ServiceReference2.HelloWorldRequestBody Body) {
this.Body = Body;
}
}
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
[System.Runtime.Serialization.DataContractAttribute(Namespace="http://tempuri.org/")]
public partial class HelloWorldRequestBody {
[System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=0)]
public CableSolve.Web.Api.Tests.ServiceReference2.ArrayOfInt ids;
public HelloWorldRequestBody() {
}
public HelloWorldRequestBody(CableSolve.Web.Api.Tests.ServiceReference2.ArrayOfInt ids) {
this.ids = ids;
}
}
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
[System.ServiceModel.MessageContractAttribute(IsWrapped=false)]
public partial class HelloWorldResponse {
[System.ServiceModel.MessageBodyMemberAttribute(Name="HelloWorldResponse", Namespace="http://tempuri.org/", Order=0)]
public CableSolve.Web.Api.Tests.ServiceReference2.HelloWorldResponseBody Body;
public HelloWorldResponse() {
}
public HelloWorldResponse(CableSolve.Web.Api.Tests.ServiceReference2.HelloWorldResponseBody Body) {
this.Body = Body;
}
}
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
[System.Runtime.Serialization.DataContractAttribute()]
public partial class HelloWorldResponseBody {
public HelloWorldResponseBody() {
}
}
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
public interface WebService1SoapChannel : CableSolve.Web.Api.Tests.ServiceReference2.WebService1Soap, System.ServiceModel.IClientChannel {
}
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
public partial class WebService1SoapClient : System.ServiceModel.ClientBase, CableSolve.Web.Api.Tests.ServiceReference2.WebService1Soap {
public WebService1SoapClient() {
}
public WebService1SoapClient(string endpointConfigurationName) :
base(endpointConfigurationName) {
}
public WebService1SoapClient(string endpointConfigurationName, string remoteAddress) :
base(endpointConfigurationName, remoteAddress) {
}
public WebService1SoapClient(string endpointConfigurationName, System.ServiceModel.EndpointAddress remoteAddress) :
base(endpointConfigurationName, remoteAddress) {
}
public WebService1SoapClient(System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress) :
base(binding, remoteAddress) {
}
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
CableSolve.Web.Api.Tests.ServiceReference2.HelloWorldResponse CableSolve.Web.Api.Tests.ServiceReference2.WebService1Soap.HelloWorld(CableSolve.Web.Api.Tests.ServiceReference2.HelloWorldRequest request) {
return base.Channel.HelloWorld(request);
}
public void HelloWorld(CableSolve.Web.Api.Tests.ServiceReference2.ArrayOfInt ids) {
CableSolve.Web.Api.Tests.ServiceReference2.HelloWorldRequest inValue = new CableSolve.Web.Api.Tests.ServiceReference2.HelloWorldRequest();
inValue.Body = new CableSolve.Web.Api.Tests.ServiceReference2.HelloWorldRequestBody();
inValue.Body.ids = ids;
CableSolve.Web.Api.Tests.ServiceReference2.HelloWorldResponse retVal = ((CableSolve.Web.Api.Tests.ServiceReference2.WebService1Soap)(this)).HelloWorld(inValue);
}
}
}
Какого черта? Почему ожидаемый тип второго параметра HelloWorld зависит от существования другого параметра, производного от абстрактного класса или являющегося им? Возможно ли, чтобы HelloWorld ожидал только идентификаторы int[] без параметра Foo, но не ожидал ArrayOfInt?
Я заметил это вчера после некоторого расследования, но был недоволен тем, что узнал об этом. Может ли кто-нибудь объяснить мне это?
Вот что я испытываю:
[list] [*]Я вижу две разные возможности сериализации:
[code][System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")][/code] [*][code][System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "4.0.0.0")][/code] [/list] [*]Сериализация с использованием Runtime.Serialization приводит к тому, что объект ArrayOf будет введен, если какие-либо коллекции ожидается в качестве параметров веб-методов. [list] public void Foo(int[] ids) ==> public void Foo(int[] ids) [b]System.ServiceModel [*]публичный void Foo(int[] ids) ==> public void Foo(ArrayOfInt ids) System.Runtime.Serialization[/b] [/list] [*]Выбранный механизм сериализации зависит от параметра, полученного из типа абстрактного класса (или являющегося им). [list] public void Bar(int[] ids) ==> Используется [b]System.Runtime.Serialization[/b]. [*]public void Bar(DerivedFromAbstractClass baz, int[] ids) ==> [b]System.ServiceModel[/b] > используется. [/list]
В качестве примера:
[code]public abstract class Foo { }
/// /// Summary description for WebService1 /// [System.Web.Services.WebService(Namespace = "http://tempuri.org/")] [System.Web.Services.WebServiceBinding(ConformsTo = System.Web.Services.WsiProfiles.BasicProfile1_1)] [System.ComponentModel.ToolboxItem(false)] // To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line. // [System.Web.Script.Services.ScriptService] public class WebService1 : System.Web.Services.WebService { [System.Web.Services.WebMethod] public void HelloWorld(Foo foo, int[] ids) { } } [/code]
Вот как выглядит мой файл .asmx. Обратите внимание на типы параметров, ожидаемые hello world. Теперь я создаю ссылку на сервис:
[code]namespace CableSolve.Web.Api.Tests.ServiceReference1 { [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] [System.ServiceModel.ServiceContractAttribute(ConfigurationName="ServiceReference1.WebService1Soap")] public interface WebService1Soap {
Обратите внимание на отсутствие ArrayOfInt. Теперь я удаляю параметр Foo из WebService1 и генерирую вторую ссылку на службу. Обратите внимание:
[code]namespace CableSolve.Web.Api.Tests.ServiceReference2 { using System.Runtime.Serialization; using System;
[System.Diagnostics.DebuggerStepThroughAttribute()] [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "4.0.0.0")] [System.Runtime.Serialization.CollectionDataContractAttribute(Name="ArrayOfInt", Namespace="http://tempuri.org/", ItemName="int")] [System.SerializableAttribute()] public class ArrayOfInt : System.Collections.Generic.List { }
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] [System.ServiceModel.ServiceContractAttribute(ConfigurationName="ServiceReference2.WebService1Soap")] public interface WebService1Soap {
// CODEGEN: Generating message contract since element name ids from namespace http://tempuri.org/ is not marked nillable [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/HelloWorld", ReplyAction="*")] CableSolve.Web.Api.Tests.ServiceReference2.HelloWorldResponse HelloWorld(CableSolve.Web.Api.Tests.ServiceReference2.HelloWorldRequest request); }
[System.Diagnostics.DebuggerStepThroughAttribute()] [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] [System.ServiceModel.MessageContractAttribute(IsWrapped=false)] public partial class HelloWorldRequest {
[System.ServiceModel.MessageBodyMemberAttribute(Name="HelloWorld", Namespace="http://tempuri.org/", Order=0)] public CableSolve.Web.Api.Tests.ServiceReference2.HelloWorldRequestBody Body;
public HelloWorldRequest() { }
public HelloWorldRequest(CableSolve.Web.Api.Tests.ServiceReference2.HelloWorldRequestBody Body) { this.Body = Body; } }
[System.Diagnostics.DebuggerStepThroughAttribute()] [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] [System.Runtime.Serialization.DataContractAttribute(Namespace="http://tempuri.org/")] public partial class HelloWorldRequestBody {
[System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=0)] public CableSolve.Web.Api.Tests.ServiceReference2.ArrayOfInt ids;
public HelloWorldRequestBody() { }
public HelloWorldRequestBody(CableSolve.Web.Api.Tests.ServiceReference2.ArrayOfInt ids) { this.ids = ids; } }
[System.Diagnostics.DebuggerStepThroughAttribute()] [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] [System.ServiceModel.MessageContractAttribute(IsWrapped=false)] public partial class HelloWorldResponse {
[System.ServiceModel.MessageBodyMemberAttribute(Name="HelloWorldResponse", Namespace="http://tempuri.org/", Order=0)] public CableSolve.Web.Api.Tests.ServiceReference2.HelloWorldResponseBody Body;
public HelloWorldResponse() { }
public HelloWorldResponse(CableSolve.Web.Api.Tests.ServiceReference2.HelloWorldResponseBody Body) { this.Body = Body; } }
[System.Diagnostics.DebuggerStepThroughAttribute()] [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] [System.Runtime.Serialization.DataContractAttribute()] public partial class HelloWorldResponseBody {
public HelloWorldResponseBody() { } }
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] public interface WebService1SoapChannel : CableSolve.Web.Api.Tests.ServiceReference2.WebService1Soap, System.ServiceModel.IClientChannel { }
[System.Diagnostics.DebuggerStepThroughAttribute()] [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")] public partial class WebService1SoapClient : System.ServiceModel.ClientBase, CableSolve.Web.Api.Tests.ServiceReference2.WebService1Soap {
public WebService1SoapClient() { }
public WebService1SoapClient(string endpointConfigurationName) : base(endpointConfigurationName) { }
public WebService1SoapClient(string endpointConfigurationName, string remoteAddress) : base(endpointConfigurationName, remoteAddress) { }
public WebService1SoapClient(string endpointConfigurationName, System.ServiceModel.EndpointAddress remoteAddress) : base(endpointConfigurationName, remoteAddress) { }
public WebService1SoapClient(System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress) : base(binding, remoteAddress) { }
public void HelloWorld(CableSolve.Web.Api.Tests.ServiceReference2.ArrayOfInt ids) { CableSolve.Web.Api.Tests.ServiceReference2.HelloWorldRequest inValue = new CableSolve.Web.Api.Tests.ServiceReference2.HelloWorldRequest(); inValue.Body = new CableSolve.Web.Api.Tests.ServiceReference2.HelloWorldRequestBody(); inValue.Body.ids = ids; CableSolve.Web.Api.Tests.ServiceReference2.HelloWorldResponse retVal = ((CableSolve.Web.Api.Tests.ServiceReference2.WebService1Soap)(this)).HelloWorld(inValue); } } } [/code]
Какого черта? [b]Почему ожидаемый тип второго параметра HelloWorld зависит от существования другого параметра, производного от абстрактного класса или являющегося им? Возможно ли, чтобы HelloWorld ожидал только идентификаторы int[] без параметра Foo, но не ожидал ArrayOfInt?[/b]