如何从服务中返回各种类型但具有相同的部分?

时间:2016-02-19 06:46:24

标签: c# wcf

我从我的服务中返回各种类型:

Destroyed()

但我想介绍一下我的服务的状态代码,它不是建立在WCF基础设施上,而是建立在我服务的内部逻辑上,如下所示:

[ServiceContract]
public interface IService
{
    [OperationContract]
    void Initialize();

    [OperationContract]
    Settings GetSettings(); // returns custom type Settings

    [OperationContract]
    void SetSettings(Settings settings);

    [OperationContract]
    bool SettingsAccepted();
}

我希望我的服务不仅返回void,bool或自定义类型,而且返回状态代码,如下所示(伪代码):

[DataContract]
public enum ServiceStatus
{
    [EnumMember]
    NormalWork = 0,

    [EnumMember]
    TimeOut,

    [EnumMember]
    DenialOfService
};

客户端的逻辑将是这样的:检查返回消息中的状态代码,如果是ServiceStatus.NormalWork,则使用返回消息的其余部分。

如何最好地组织它?我是否引入了一个基类来返回(使用DataContract属性),然后根据每个返回值(每个操作契约)从中创建新的派生类?还是有更好的方法?也许在WCF中有一个内置的基础设施用于这样的任务 - 将自定义状态代码与自定义返回类型一起返回?

2 个答案:

答案 0 :(得分:1)

您可以尝试创建名为ServiceResponse<T>的类,并使用属性,您需要具有类型为T的状态和属性,其中将是实际返回的对象。

当然,在此方法中,当结果类型为ServiceResponse<bool>时,所有方法都会返回bool

看起来像这样:

[DataContract]
public class ServiceResponse<T>
{
  [DataMember]
  ServiceStatus Status { get; set; }

  [DataMember]
  T Payload { get; set; }
}

此类还可以包含对用户的消息,异常,错误以及可以用来处理来自WCF的正确响应的任何内容。

然后在WCF中的使用将是:

[OperationContract]
    ServiceResponse<bool> SettingsAccepted();

答案 1 :(得分:1)

  

客户端的逻辑将是这样的:检查返回消息中的状态代码,如果是ServiceStatus.NormalWork,则执行返回消息的其余部分。

如果你真的想要这个,那么另一个答案就是创造这样一个野兽的所有细节。 然而,请不要这样做。如果您的服务无法正常工作,请抛出异常。它会自动转换为故障。

返回代码是1980年。我已经必须进行异常处理。您的服务可能不可用,网络可能已关闭或可能存在任何其他故障。所以我已经有了异常处理,现在使用你提出的方法,我需要异常处理返回代码处理。随着每一个电话。太糟糕了。此外,人们可能会更容易犯错误。他们可能只是接受交付的值而忘记检查您的返回代码。除了例外,这种错误永远不会发生。

如果您希望服务失败并显示“DenialOfService”错误,那么请创建一个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();
}