如何返回具有泛型属性的 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返回类型,我将如何做到这一点?
型是一种在编译时添加类型安全的工具。因此,必须在编译时知道类的使用者使用的具体类型。如果创建函数
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;
}
如果您的SuccessData
和ErrorData
实现相同的接口,那么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问答可以处理该特定方面。