【发布时间】:2013-08-05 08:30:52
【问题描述】:
假设您有一个返回 IEnumerable 的请求类 AllCustomers
[Route("/customers")]
public class AllCustomers : IReturn<IEnumerable<Customer>>
{
}
如果您转到该请求的元数据页面,您将遇到以下崩溃:
[MemberAccessException: Cannot create an abstract class.]
System.Runtime.Serialization.FormatterServices.nativeGetUninitializedObject(RuntimeType type) +0
System.Runtime.Serialization.FormatterServices.GetUninitializedObject(Type type) +56
ServiceStack.Text.<>c__DisplayClass3.<GetConstructorMethodToCache>b__1() +38
ServiceStack.Text.ReflectionExtensions.CreateInstance(Type type) +64
ServiceStack.WebHost.Endpoints.Metadata.JsonMetadataHandler.CreateMessage(Type dtoType) +49
ServiceStack.WebHost.Endpoints.Metadata.BaseMetadataHandler.CreateResponse(Type type) +267
ServiceStack.WebHost.Endpoints.Metadata.BaseMetadataHandler.ProcessOperations(HtmlTextWriter writer, IHttpRequest httpReq, IHttpResponse httpRes) +688
ServiceStack.WebHost.Endpoints.Metadata.BaseMetadataHandler.Execute(HttpContext context) +267
ServiceStack.WebHost.Endpoints.Support.HttpHandlerBase.ProcessRequest(HttpContext context) +84
System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +341
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +69
我认为当给定请求的响应是 IEnumerable 时,元数据页面的实现不应该崩溃,因为这是实现服务接口的一种完全有效的方式(并且比返回列表更可取)。如果它认为 IEnumerable 作为返回类型,它应该足够聪明地为示例部分实例化一个列表。如果返回类型不可实例化,至少它不应该崩溃......
【问题讨论】:
-
您确定问题出在
IEnumerable上吗?如果您在IReturn声明中将IEnumerable更改为IList或只是List,您会得到同样的异常吗?Customer类是如何声明的? -
您是否只是要从上下文中获取一揽子建议并将其应用于每种情况?这正是货物崇拜心态的传播方式。这与定义服务 API 边界或 ServiceStack 无关。我已经提供了一个链接,指向跨进程边界使用接口的实际实现问题以及它如何违反服务的核心租户 - 请随意忽略它并遵循 Internet 上您认为更相关和特定于您的使用的替代建议-案例。
-
您在链接中谈到的实现问题不适用于此处:当您指定 IEnumerable
作为返回类型时,Json 中不需要传递任何类型信息。如果 DTO 使用 IReturn > 或 IReturn - >,这将使 Json 膨胀。我在公共 API 中使用列表的问题是它给出了 API 的错误表示:它表明客户端可以从服务调用的结果中添加或删除显然只对本地集合这样做。只是想在这里进行建设性的讨论。
标签: c# servicestack