如何从服务中返回各种类型的产品,但具有相同的部分
本文关键字:服务 返回 类型 种类 | 更新日期: 2023-09-27 18:35:23
我从我的服务中返回各种类型:
[ServiceContract]
public interface IService
{
[OperationContract]
void Initialize();
[OperationContract]
Settings GetSettings(); // returns custom type Settings
[OperationContract]
void SetSettings(Settings settings);
[OperationContract]
bool SettingsAccepted();
}
但是,我想为我的服务引入状态代码,该代码不是基于 WCF 基础结构构建的,而是基于我的服务的内部逻辑构建的,如下所示:
[DataContract]
public enum ServiceStatus
{
[EnumMember]
NormalWork = 0,
[EnumMember]
TimeOut,
[EnumMember]
DenialOfService
};
我希望我的服务不仅返回 void、bool 或自定义类型,还返回带有状态代码的它们,如下所示(伪代码):
[ServiceContract]
public interface IService
{
[OperationContract]
(ServiceStatus) Initialize();
[OperationContract]
(ServiceStatus, Settings) GetSettings();
[OperationContract]
(ServiceStatus) SetSettings(Settings settings);
[OperationContract]
(ServiceStatus, bool) SettingsAccepted();
}
客户端的逻辑是这样的:检查返回消息中的状态代码,如果是ServiceStatus.NormalWork,则使用返回消息的其余部分。
如何最好地组织它?我是否引入了要返回的基类(使用 DataContract 属性),然后根据每个返回值(每个操作协定)从中创建新的派生类?还是有更好的方法?也许 WCF 中有一个内置的基础结构用于这样的任务 - 将自定义状态代码与自定义返回类型一起返回?
客户端的逻辑是这样的:检查返回消息中的状态代码,如果是ServiceStatus.NormalWork,则使用返回消息的其余部分。
如果你真的想要这个,另一个答案有创造这样一个野兽的所有细节。但是,请不要这样做。如果服务无法正常工作,请引发异常。它将自动转换为故障。
返回代码是 1980 年。我已经必须进行异常处理。您的服务可能不可用,网络可能已关闭或可能存在任何其他故障。所以我已经有了异常处理,现在使用您提出的方法,我需要异常处理和返回代码处理。每一次通话。糟糕透了。此外,人们可能会更容易犯错误。他们可能只是获取传递的值,而忘记检查您的返回代码。除了例外,这个错误永远不会发生。
如果您希望您的服务失败并显示"拒绝服务"的错误,那么请创建一个DenialOfServiceException
并将其抛出。不要使用返回代码。这不是 WCF 报告错误的方式。
如果你确实想要一个固定的结构,你可以使用另一个答案的模板方法,或者你可以使用继承:
[DataContract]
public class ServiceResponse
{
[DataMember]
public ServiceStatus Status { get; set; }
}
[DataContract]
public class SettingsAcceptedResponse : ServiceResponse
{
[DataMember]
public bool Result { get; set; }
}
[ServiceContract]
public interface IService
{
// [...]
[OperationContract]
ServiceResponse SetSettings(Settings settings);
[OperationContract]
SettingsAcceptedResponse SettingsAccepted();
}
您可以尝试创建名为 ServiceResponse<T>
的类,并且使用属性,您需要具有 T
类型的状态和属性,其中将是真正的返回对象。
当然,在这种方法中,当结果类型为bool
时,所有方法都将返回ServiceResponse<bool>
它可能看起来像这样:
[DataContract]
public class ServiceResponse<T>
{
[DataMember]
ServiceStatus Status { get; set; }
[DataMember]
T Payload { get; set; }
}
此类还可以包含发送给用户的消息、异常、错误以及可用于正确处理来自 WCF 的响应的任何内容。
那么在 WCF 中的用法将是:
[OperationContract]
ServiceResponse<bool> SettingsAccepted();