.NET Core System.ServiceModel WCF 客户端可以指定非标准默认值吗?

问题描述 投票:0回答:1

我正在将一些 Xamarin.Android 和 Xamarin.iOS 应用程序迁移到 .NET 8。这些应用程序与 WCF 服务进行通信。 以前,这些应用程序使用 Web 引用 WCF 客户端(右键单击项目 -> 添加 -> Web 引用),它为任何布尔值和整数字段添加带有后缀“Specified”的参数和属性。 现在,我们正在迁移到使用连接服务 WCF 客户端(右键单击项目 -> 添加 -> 连接服务 -> 添加 WCF Web 服务),该客户端类似,但没有任何“指定”参数或属性。

总的来说,我不会错过指定的参数和属性,因为它们通常是不必要的样板。 然而,在我们的应用程序中有一些地方,如果服务器没有指定它们,我们希望布尔变量默认为 True 而不是 False。 在我们的用例中,这可能是由于服务器已过时并且合约版本较旧,尽管根据我的理解,将 EmitDefaultValue 设置为 False 也可能导致此问题,并且可能是此问题的更可接受的示例。

这是一个例子。

服务版本1:

[ServiceContract(Namespace = "http://test.wcf.service")]
public interface IMobileCommunicationService
{
    [OperationContract]
    TestDTO Test();
}

public class TestDTO
{
    public string Hello;
}

服务版本2:

[ServiceContract(Namespace = "http://test.wcf.service")]
public interface IMobileCommunicationService
{
    [OperationContract]
    TestDTO Test();
}

public class TestDTO
{
    public string Hello;

    public bool World;
}

来自 WCF 客户端的 Reference.cs 文件的 TestDTO。 通过 Xamarin 应用程序可以使用的 Web 参考生成:

/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "4.8.9037.0")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://schemas.datacontract.org/2004/07/SalesPad.DataCollection.Service")]
public partial class TestDTO {
    
    private string helloField;
    
    private bool worldField;
    
    private bool worldFieldSpecified;
    
    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute(IsNullable=true)]
    public string Hello {
        get {
            return this.helloField;
        }
        set {
            this.helloField = value;
        }
    }
    
    /// <remarks/>
    public bool World {
        get {
            return this.worldField;
        }
        set {
            this.worldField = value;
        }
    }
    
    /// <remarks/>
    [System.Xml.Serialization.XmlIgnoreAttribute()]
    public bool WorldSpecified {
        get {
            return this.worldFieldSpecified;
        }
        set {
            this.worldFieldSpecified = value;
        }
    }
}

来自 WCF 客户端的 Reference.cs 文件的 TestDTO。 通过 .NET 8 Android 和 iOS 应用程序可以使用的连接服务生成:

[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "2.2.0-preview1.23462.5")]
[System.Runtime.Serialization.DataContractAttribute(Name="TestDTO", Namespace="http://schemas.datacontract.org/2004/07/SalesPad.DataCollection.Service")]
public partial class TestDTO : object
{
    
    private string HelloField;
    
    private bool WorldField;
    
    [System.Runtime.Serialization.DataMemberAttribute()]
    public string Hello
    {
        get
        {
            return this.HelloField;
        }
        set
        {
            this.HelloField = value;
        }
    }
    
    [System.Runtime.Serialization.DataMemberAttribute()]
    public bool World
    {
        get
        {
            return this.WorldField;
        }
        set
        {
            this.WorldField = value;
        }
    }
}

如果服务未指定 World 的值(例如服务是服务的版本 1),旧客户端可以使用该代码将“World”默认为“true”:

dto.World = dto.WorldSpecified ? dto.World : true;

我对 WorldSpecified 属性不存在感到满意,因为我不关心该属性本身。 但是,如果服务未指定 World,则 WorldSpecified 属性提供了一种将 World 默认为 True 而不是 False 的方法。

有什么方法可以使用较新的连接服务 WCF 客户端让 World 默认为 True 吗?

我尝试向我的 DTO 对象之一添加无参数构造函数,但该构造函数没有被调用。 我能想到的唯一解决方法是手动更改 Reference.cs 文件(我想避免这样做,因为它很难维护)或“牺牲”Hello 字段作为荒谬的黑客攻击的一部分,这是不值得尝试的解释一下。

c# wcf .net-core
1个回答
0
投票

在 C# 中,Boolean 变量的默认值为 false。 默认值

所以我认为你可以将代码修改为:

[ServiceContract(Namespace = "http://test.wcf.service")]
public interface IMobileCommunicationService
{
    [OperationContract]
    TestDTO Test();
}

public class TestDTO
{
    public string Hello;

    public bool World=true;
}

更新:

我写了一个例子给你参考:

IService1.cs:

  [ServiceContract]
    public interface IService1
    {
        [OperationContract]
    TestDTO Test(TestDTO testDTO);
}



[DataContract]
public class TestDTO
{
    [DataMember]
    public bool World=true;
}

服务1.svc

public TestDTO Test(TestDTO data)
 {
     data.World= true;
     return data;
 }

客户:

 ServiceReference1.Service1Client client = new ServiceReference1.Service1Client();
 TestDTO data = new TestDTO();
 data=client.Test(data);
 Console.WriteLine(data.World.ToString());
 Console.ReadLine();

输出:

enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.