如何返回具有泛型属性的 C# Web 服务

本文关键字:属性 泛型 服务 Web 何返回 返回 | 更新日期: 2023-09-27 18:09:39

我正在创建一个 Web 服务,并希望在返回数据方面更加优雅,而不是拥有许多使用者需要检查的属性。

根据幕后生成的数据,我需要能够返回错误数据或使用者期望的数据。

与其拥有一个大的平面对象,并在需要时填充属性,并让用户检查"成功"标志,我希望单个属性 Data 是错误类的实例或成功类的实例。

这就是我想做的:

class ItemResponse
{
    public bool Success { get; set; }
    public T Data{ get; set; }
}
if( /*acceptance criteria*/ )
{
    ItemResponse<SuccessData> resp = new ItemResponse<SuccessData>();
    resp.Data = new SuccessData();
}
else
{
    ItemResponse<ErrorData> resp = new ItemResponse<ErrorData>();
    resp.Data = new ErrorData();
}
return resp;

public class SuccessData
{
}
public class ErrorData
{
}

然后让 web 方法返回具有泛型属性的对象。

这是否可能,如果是这样,鉴于必须正确键入 webmethod返回类型,我将如何做到这一点?

如何返回具有泛型属性的 C# Web 服务

型是一种在编译时添加类型安全的工具。因此,必须在编译时知道类的使用者使用的具体类型。如果创建函数

List<T> myFunction<T>() {...}

。然后你需要在调用它时指定T,例如

var myResult = myFunction<int>();

。这使得具体类型在编译时已知。(即使不指定T因为它可以推断,具体类型在编译时也是已知的。

但是,您希望在run-time确定Data的通用类型:如果发生错误,则返回ItemResponse<SuccessData>,否则返回ItemResponse<ErrorData>。这不是泛型的工作方式。

简短的版本,你不能按照你的建议去做。

长(呃(版本 A部分

Web 服务

可以被视为类的方法,实际上是 Web 服务类之外的方法。 我建议查看一些 Web 服务教程,以便更好地掌握设置 Web 服务背后的机制。 MSDN 有许多特定于Microsoft堆栈的教程,可通过您喜欢的搜索引擎轻松找到这些教程。

方法的返回对象不允许具有多态行为,这本质上是您所要求的。

此伪代码等效于您尝试创建的代码,这就是编译器不允许它的原因。 它不知道您尝试呼叫哪个DoSomething()

class myFoo
{
     public SuccessResponse DoSomething() {....}  
     public ErrorResponse DoSomething() {....}
}

或者,您可以设想如下:

public [SuccessResponse | ErrorResponse] DoSomething()但这失败了,原因也应该是显而易见的。 C# 根本不支持多态返回。

B部分即使我们只关注resp.Data,该对象仍然必须声明为某种类型。

class Response
{
     public Collection<someType> Data;
}

如果您的SuccessDataErrorData实现相同的接口,那么someType可能只是IyourInterface,但这引发了另一个问题。 也就是说,最终用户如何知道他们是否在Data中获得了良好的数据,或者是否有错误响应隐藏在那里。

我相信,只要将 WCF 声明为 WCF 服务对象的公共部分,WCF 就可以为您序列化IyourInterface。 但这仍然不能解决最终用户如何知道该怎么做。


如果您愿意在响应中不那么优雅,经典模式是简单地将成功数据和错误对象捆绑到另一个响应类中,如下所示:

class myResponse
{
    public SuccessResponse myRespData;
    public ErrorResponse myError
}

现在,最终用户检查是否存在错误,如果他们关心。 假设没有错误,然后他们去查看响应数据。


根据您的评论,是的,您也可以执行以下操作:

class Response
{
    public List<IYourData> Data;
    public YourEnum ReturnType;
}
public class ResponseData : IYourData { ... }  
public class ErrorData : IYourData { ... }  

然后在客户端上,您可以执行如下简单检查:

if( ReturnType == YourEnum.Success ) { ... }  
else if( ReturnType == YourEnum.Error ) { ... }  
else ... 

WCF 将为您处理List的序列化。 它将转换为数组或直接传递集合,具体取决于您拥有的设置。 有一些SO问答可以处理该特定方面。