Почему механизм сериализации веб-сервисов Visual Studio меняется, когда я ссылаюсь на абстрактный класс?C#

Место общения программистов C#
Ответить
Anonymous
 Почему механизм сериализации веб-сервисов Visual Studio меняется, когда я ссылаюсь на абстрактный класс?

Сообщение Anonymous »

Я заметил это вчера после некоторого расследования, но был недоволен тем, что узнал об этом. Может ли кто-нибудь объяснить мне это?

Вот что я испытываю:
  • Я вижу две разные возможности сериализации:

    Код: Выделить всё

    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
  • Код: Выделить всё

    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "4.0.0.0")]
[*]Сериализация с использованием 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.ServiceReference1 {
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
[System.ServiceModel.ServiceContractAttribute(ConfigurationName="ServiceReference1.WebService1Soap")]
public interface WebService1Soap {

[System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/HelloWorld", ReplyAction="*")]
[System.ServiceModel.XmlSerializerFormatAttribute(SupportFaults=true)]
void HelloWorld(CableSolve.Web.Api.Tests.ServiceReference1.Foo foo, int[] ids);
}

/// 
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "4.0.30319.233")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://tempuri.org/")]
public abstract partial class Foo : object, System.ComponentModel.INotifyPropertyChanged {

public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;

protected void RaisePropertyChanged(string propertyName) {
System.ComponentModel.PropertyChangedEventHandler propertyChanged = this.PropertyChanged;
if ((propertyChanged != null)) {
propertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName));
}
}
}

[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
public interface WebService1SoapChannel : CableSolve.Web.Api.Tests.ServiceReference1.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.ServiceReference1.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.ServiceReference1.Foo foo, int[] ids) {
base.Channel.HelloWorld(foo, ids);
}
}
}
Обратите внимание на отсутствие ArrayOfInt. Теперь я удаляю параметр Foo из WebService1 и генерирую вторую ссылку на службу. Обратите внимание:

Код: Выделить всё

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?

Подробнее здесь: https://stackoverflow.com/questions/124 ... i-make-ref
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»