我正在将一些 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# 中,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();
输出: