ServiceStack 元数据页面抛出 MemberAccessException:无法创建抽象类

Posted

技术标签:

【中文标题】ServiceStack 元数据页面抛出 MemberAccessException:无法创建抽象类【英文标题】:ServiceStack metadata page throws MemberAccessException: Cannot create an abstract class 【发布时间】: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 类是如何声明的? 接口绝对是not a perfect valid way to define service interfaces。 很多人说,returning List<T> in public APIs is not a good practice。我同意Krzysztof Cwalina's recommendation 您是否只是要从上下文中获取一揽子建议并将其应用于每种情况?这正是货物崇拜心态的传播方式。这与定义服务 API 边界或 ServiceStack 无关。我已经提供了一个链接,指向跨进程边界使用接口的实际实现问题以及它如何违反服务的核心租户 - 请随意忽略它并遵循 Internet 上您认为更相关和特定于您的使用的替代建议-案例。 您在链接中谈到的实现问题不适用于此处:当您指定 IEnumerable 作为返回类型时,Json 中不需要传递任何类型信息。如果 DTO 使用 IReturn> 或 IReturn>,这将使 Json 膨胀。我在公共 API 中使用列表的问题是它给出了 API 的错误表示:它表明客户端可以从服务调用的结果中添加或删除显然只对本地集合这样做。只是想在这里进行建设性的讨论。 【参考方案1】:

ServiceStack 希望您将响应封装在它自己的类中。因此,您将创建一个带有 Customers IEnumerable 属性的 AllCustomerResponse 类。

【讨论】:

那个used to be the case,现在是New API supports clean responses。问题在于使用接口来定义服务层。 我一直在使用新的 API,但没有注意到这个变化。谢谢!

以上是关于ServiceStack 元数据页面抛出 MemberAccessException:无法创建抽象类的主要内容,如果未能解决你的问题,请参考以下文章

ServiceStack 5.13.0 元数据和 swagger-ui 页面在 .NET 6 迁移后返回 500 错误

ServiceStack - 检查单元测试中的 WSDL 更改

ServiceStack:错误未序列化到响应状态

ServiceStack.RabbitMQ在站点中使用时导致静态页面无法正常解析

带有 IIS 7.5 的 ServiceStack

使用 Cors 问题跨域调用 ServiceStack 服务