C# 自定义 Class 在 WCF 服务中不工作
C# Custom Class is not working in WCF service
问题
我有一项新的 WCF
服务。其中有一个 Interface
和相关的 class,只有两个方法,如以下代码所示。我在其中一种方法中使用自定义 class CompanyDetail
但出现问题,我在我的客户端项目中引用了此服务但没有任何效果。服务已连接但无法在代码中使用。
我试过的
namespace IntelliWcfService
{
[ServiceContract]
public interface IIntelliService
{
[OperationContract]
CompanyDetail GetCompanyDetails();
[OperationContract]
string Get(int value);
}
}
接口实现
namespace IntelliWcfService
{
public class IntelliService : IIntelliService
{
public CompanyDetail GetCompanyDetails()
{
try
{
var company = new CompanyDetail
{
CompanyName = "Visual Labs Pakistan",
City = "Multan",
Contact1 = "0306-8513103",
Contact2 = "",
Country = "Pakistan",
CountryCode = "+92",
Email = "VisualLabs@gmail.com",
NTN = "0007923-7",
PostalCode = "60000",
Street = "Street 2 Near Bypass Multan",
Type = "Software Technology"
};
return company;
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
}
}
public string Get(int value)
{
return "Connected";
}
}
}
公司详情Class
using System.Runtime.Serialization;
namespace IntelliWcfService.Models
{
[DataContract]
public class CompanyDetail
{
private string _companyName;
private string _ntn;
private string _type;
private string _country;
private string _countryCode;
private string _city;
private string _street;
private string _postalCode;
private string _contact1;
private string _contact2;
private string _email;
[DataMember]
public string CompanyName
{
get => _companyName;
set => _companyName = value;
}
[DataMember]
public string NTN
{
get => _ntn;
set => _ntn = value;
}
[DataMember]
public string Type
{
get => _type;
set => _type = value;
}
[DataMember]
public string Country
{
get => _country;
set => _country = value;
}
[DataMember]
public string CountryCode
{
get => _countryCode;
set => _countryCode = value;
}
[DataMember]
public string City
{
get => _city;
set => _city = value;
}
[DataMember]
public string Street
{
get => _street;
set => _street = value;
}
[DataMember]
public string PostalCode
{
get => _postalCode;
set => _postalCode = value;
}
[DataMember]
public string Contact1
{
get => _contact1;
set => _contact1 = value;
}
[DataMember]
public string Contact2
{
get => _contact2;
set => _contact2 = value;
}
[DataMember]
public string Email
{
get => _email;
set => _email = value;
}
}
}
我已经尝试过使用 [DataMember]
装饰器的自动属性并且喜欢这个完整的道具。但仍然没有任何效果。并在我的客户端中获取它。
结果
我已经在这里寻求帮助,但看来我没有做错任何事情。
Adding classes to WCF service library
https://docs.microsoft.com/en-us/dotnet/framework/wcf/feature-details/using-data-contracts
观察
当我删除 GetCompnyDetails
的这种方法时,一切正常,我可以在我的客户端中使用其他方法。同样在过去,我曾经有 EntityFramework
自动生成的模型在服务中并且曾经工作正常。
预期行为
显然我应该能够在我的客户端项目中使用所有方法。并且这个自定义 class 应该起作用,这是导致问题的原因。
添加服务引用对话框
我用你的代码创建了一个 WCF 服务,它 运行 成功了。
namespace ConsoleApp37
{
[ServiceContract]
public interface IIntelliService
{
[OperationContract]
CompanyDetail GetCompanyDetails();
[OperationContract]
string Get(int value);
}
[DataContract]
public class CompanyDetail
{
private string _companyName;
private string _ntn;
private string _type;
private string _country;
private string _countryCode;
private string _city;
private string _street;
private string _postalCode;
private string _contact1;
private string _contact2;
private string _email;
[DataMember]
public string CompanyName
{
get => _companyName;
set => _companyName = value;
}
[DataMember]
public string NTN
{
get => _ntn;
set => _ntn = value;
}
[DataMember]
public string Type
{
get => _type;
set => _type = value;
}
[DataMember]
public string Country
{
get => _country;
set => _country = value;
}
[DataMember]
public string CountryCode
{
get => _countryCode;
set => _countryCode = value;
}
[DataMember]
public string City
{
get => _city;
set => _city = value;
}
[DataMember]
public string Street
{
get => _street;
set => _street = value;
}
[DataMember]
public string PostalCode
{
get => _postalCode;
set => _postalCode = value;
}
[DataMember]
public string Contact1
{
get => _contact1;
set => _contact1 = value;
}
[DataMember]
public string Contact2
{
get => _contact2;
set => _contact2 = value;
}
[DataMember]
public string Email
{
get => _email;
set => _email = value;
}
}
public class IntelliService : IIntelliService
{
public CompanyDetail GetCompanyDetails()
{
try
{
var company = new CompanyDetail
{
CompanyName = "Visual Labs Pakistan",
City = "Multan",
Contact1 = "0306-8513103",
Contact2 = "",
Country = "Pakistan",
CountryCode = "+92",
Email = "VisualLabs@gmail.com",
NTN = "0007923-7",
PostalCode = "60000",
Street = "Street 2 Near Bypass Multan",
Type = "Software Technology"
};
return company;
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
}
}
public string Get(int value)
{
return "Connected";
}
}
class Program
{
static void Main(string[] args)
{
// Step 1: Create a URI to serve as the base address.
Uri baseAddress = new Uri("http://localhost:8000/GettingStarted/");
// Step 2: Create a ServiceHost instance.
ServiceHost selfHost = new ServiceHost(typeof(IntelliService), baseAddress);
try
{
// Step 3: Add a service endpoint.
selfHost.AddServiceEndpoint(typeof(IIntelliService), new WSHttpBinding(), "CalculatorService");
// Step 4: Enable metadata exchange.
ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
smb.HttpGetEnabled = true;
selfHost.Description.Behaviors.Add(smb);
// Step 5: Start the service.
selfHost.Open();
Console.WriteLine("The service is ready.");
// Close the ServiceHost to stop the service.
Console.WriteLine("Press <Enter> to terminate the service.");
Console.WriteLine();
Console.ReadLine();
selfHost.Close();
}
catch (CommunicationException ce)
{
Console.WriteLine("An exception occurred: {0}", ce.Message);
selfHost.Abort();
}
}
}
}
这是 server-side 代码。
客户端根据服务器端点生成代理class调用服务
我成功调用了 GetCompanyDetails 方法并打印了城市的值 属性。
更新
根据您的描述,我创建了一个 UWP 程序来调用 WCF,如下所示:
这是ButtonBase_OnClick:
private async void ButtonBase_OnClick(object sender, RoutedEventArgs e) {
BasicHttpBinding binding = new BasicHttpBinding();
EndpointAddress endpointAddress = new EndpointAddress("http://localhost:8000/GettingStarted/CalculatorService");
ServiceReference1.IntelliServiceClient intelliServiceClient = new ServiceReference1.IntelliServiceClient(binding,endpointAddress);
ServiceReference1.CompanyDetail companyDetail= await intelliServiceClient.GetCompanyDetailsAsync();
MessageDialog message = new MessageDialog(companyDetail.City);
await message.ShowAsync();
}
您的客户端项目似乎无法引用自定义类型。
自定义类型可能是完整的。 NET项目和clinet是。净芯.
尝试将引用配置为不重用引用类型
因此它们将在您的客户端项目中生成并可以使用。
另一种选择是将您的自定义类型和合同分开。 Net 标准 2.0 项目,并受到客户和服务的尊重。您可以选中 'reuse' 复选框。
在大多数情况下,在您有解决方案内参考的情况下,重用是有意义的,这就是它被预先选择的原因。
问题
我有一项新的 WCF
服务。其中有一个 Interface
和相关的 class,只有两个方法,如以下代码所示。我在其中一种方法中使用自定义 class CompanyDetail
但出现问题,我在我的客户端项目中引用了此服务但没有任何效果。服务已连接但无法在代码中使用。
我试过的
namespace IntelliWcfService
{
[ServiceContract]
public interface IIntelliService
{
[OperationContract]
CompanyDetail GetCompanyDetails();
[OperationContract]
string Get(int value);
}
}
接口实现
namespace IntelliWcfService
{
public class IntelliService : IIntelliService
{
public CompanyDetail GetCompanyDetails()
{
try
{
var company = new CompanyDetail
{
CompanyName = "Visual Labs Pakistan",
City = "Multan",
Contact1 = "0306-8513103",
Contact2 = "",
Country = "Pakistan",
CountryCode = "+92",
Email = "VisualLabs@gmail.com",
NTN = "0007923-7",
PostalCode = "60000",
Street = "Street 2 Near Bypass Multan",
Type = "Software Technology"
};
return company;
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
}
}
public string Get(int value)
{
return "Connected";
}
}
}
公司详情Class
using System.Runtime.Serialization;
namespace IntelliWcfService.Models
{
[DataContract]
public class CompanyDetail
{
private string _companyName;
private string _ntn;
private string _type;
private string _country;
private string _countryCode;
private string _city;
private string _street;
private string _postalCode;
private string _contact1;
private string _contact2;
private string _email;
[DataMember]
public string CompanyName
{
get => _companyName;
set => _companyName = value;
}
[DataMember]
public string NTN
{
get => _ntn;
set => _ntn = value;
}
[DataMember]
public string Type
{
get => _type;
set => _type = value;
}
[DataMember]
public string Country
{
get => _country;
set => _country = value;
}
[DataMember]
public string CountryCode
{
get => _countryCode;
set => _countryCode = value;
}
[DataMember]
public string City
{
get => _city;
set => _city = value;
}
[DataMember]
public string Street
{
get => _street;
set => _street = value;
}
[DataMember]
public string PostalCode
{
get => _postalCode;
set => _postalCode = value;
}
[DataMember]
public string Contact1
{
get => _contact1;
set => _contact1 = value;
}
[DataMember]
public string Contact2
{
get => _contact2;
set => _contact2 = value;
}
[DataMember]
public string Email
{
get => _email;
set => _email = value;
}
}
}
我已经尝试过使用 [DataMember]
装饰器的自动属性并且喜欢这个完整的道具。但仍然没有任何效果。并在我的客户端中获取它。
结果
我已经在这里寻求帮助,但看来我没有做错任何事情。
Adding classes to WCF service library
https://docs.microsoft.com/en-us/dotnet/framework/wcf/feature-details/using-data-contracts
观察
当我删除 GetCompnyDetails
的这种方法时,一切正常,我可以在我的客户端中使用其他方法。同样在过去,我曾经有 EntityFramework
自动生成的模型在服务中并且曾经工作正常。
预期行为
显然我应该能够在我的客户端项目中使用所有方法。并且这个自定义 class 应该起作用,这是导致问题的原因。
添加服务引用对话框
我用你的代码创建了一个 WCF 服务,它 运行 成功了。
namespace ConsoleApp37
{
[ServiceContract]
public interface IIntelliService
{
[OperationContract]
CompanyDetail GetCompanyDetails();
[OperationContract]
string Get(int value);
}
[DataContract]
public class CompanyDetail
{
private string _companyName;
private string _ntn;
private string _type;
private string _country;
private string _countryCode;
private string _city;
private string _street;
private string _postalCode;
private string _contact1;
private string _contact2;
private string _email;
[DataMember]
public string CompanyName
{
get => _companyName;
set => _companyName = value;
}
[DataMember]
public string NTN
{
get => _ntn;
set => _ntn = value;
}
[DataMember]
public string Type
{
get => _type;
set => _type = value;
}
[DataMember]
public string Country
{
get => _country;
set => _country = value;
}
[DataMember]
public string CountryCode
{
get => _countryCode;
set => _countryCode = value;
}
[DataMember]
public string City
{
get => _city;
set => _city = value;
}
[DataMember]
public string Street
{
get => _street;
set => _street = value;
}
[DataMember]
public string PostalCode
{
get => _postalCode;
set => _postalCode = value;
}
[DataMember]
public string Contact1
{
get => _contact1;
set => _contact1 = value;
}
[DataMember]
public string Contact2
{
get => _contact2;
set => _contact2 = value;
}
[DataMember]
public string Email
{
get => _email;
set => _email = value;
}
}
public class IntelliService : IIntelliService
{
public CompanyDetail GetCompanyDetails()
{
try
{
var company = new CompanyDetail
{
CompanyName = "Visual Labs Pakistan",
City = "Multan",
Contact1 = "0306-8513103",
Contact2 = "",
Country = "Pakistan",
CountryCode = "+92",
Email = "VisualLabs@gmail.com",
NTN = "0007923-7",
PostalCode = "60000",
Street = "Street 2 Near Bypass Multan",
Type = "Software Technology"
};
return company;
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
}
}
public string Get(int value)
{
return "Connected";
}
}
class Program
{
static void Main(string[] args)
{
// Step 1: Create a URI to serve as the base address.
Uri baseAddress = new Uri("http://localhost:8000/GettingStarted/");
// Step 2: Create a ServiceHost instance.
ServiceHost selfHost = new ServiceHost(typeof(IntelliService), baseAddress);
try
{
// Step 3: Add a service endpoint.
selfHost.AddServiceEndpoint(typeof(IIntelliService), new WSHttpBinding(), "CalculatorService");
// Step 4: Enable metadata exchange.
ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
smb.HttpGetEnabled = true;
selfHost.Description.Behaviors.Add(smb);
// Step 5: Start the service.
selfHost.Open();
Console.WriteLine("The service is ready.");
// Close the ServiceHost to stop the service.
Console.WriteLine("Press <Enter> to terminate the service.");
Console.WriteLine();
Console.ReadLine();
selfHost.Close();
}
catch (CommunicationException ce)
{
Console.WriteLine("An exception occurred: {0}", ce.Message);
selfHost.Abort();
}
}
}
}
这是 server-side 代码。
客户端根据服务器端点生成代理class调用服务
我成功调用了 GetCompanyDetails 方法并打印了城市的值 属性。
更新
根据您的描述,我创建了一个 UWP 程序来调用 WCF,如下所示:
这是ButtonBase_OnClick:
private async void ButtonBase_OnClick(object sender, RoutedEventArgs e) {
BasicHttpBinding binding = new BasicHttpBinding();
EndpointAddress endpointAddress = new EndpointAddress("http://localhost:8000/GettingStarted/CalculatorService");
ServiceReference1.IntelliServiceClient intelliServiceClient = new ServiceReference1.IntelliServiceClient(binding,endpointAddress);
ServiceReference1.CompanyDetail companyDetail= await intelliServiceClient.GetCompanyDetailsAsync();
MessageDialog message = new MessageDialog(companyDetail.City);
await message.ShowAsync();
}
您的客户端项目似乎无法引用自定义类型。
自定义类型可能是完整的。 NET项目和clinet是。净芯.
尝试将引用配置为不重用引用类型
因此它们将在您的客户端项目中生成并可以使用。
另一种选择是将您的自定义类型和合同分开。 Net 标准 2.0 项目,并受到客户和服务的尊重。您可以选中 'reuse' 复选框。
在大多数情况下,在您有解决方案内参考的情况下,重用是有意义的,这就是它被预先选择的原因。