1

Let's say you have a request class AllCustomers that returns an IEnumerable

[Route("/customers")]
public class AllCustomers : IReturn<IEnumerable<Customer>>
{
}

If you go to the metadata page for that request you will get the following crash:

[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

I think the implementation of the metadata page should not crash when the response for a given request is an IEnumerable because this is a perfectly valid way to implement interfaces to your services (and its more preferable than returning a List). It should be smart enough to instantiate a List for the samples section if it sees IEnumerable as the return type. At least it shouldn't crash if the return type isn't instantiable...

Guy Godin
  • 448
  • 5
  • 16
  • Are you sure the problem is with `IEnumerable`? If you change `IEnumerable` to `IList` or just `List` in your `IReturn` declaration, do you get the same exception? How is the `Customer` class declared? – Mike Mertsock Aug 05 '13 at 13:55
  • 2
    Interfaces are most definitely [not a perfect valid way to define service interfaces](http://stackoverflow.com/a/10759250/85785). – mythz Aug 05 '13 at 14:03
  • Well according to lots of folks, [returning List in public APIs is not a good practice](http://stackoverflow.com/questions/387937/why-is-it-considered-bad-to-expose-listt). I agree with [Krzysztof Cwalina's recommendation](http://blogs.msdn.com/b/kcwalina/archive/2005/09/26/474010.aspx) – Guy Godin Aug 05 '13 at 23:01
  • Are you just going to take blanket advice out of a context and apply it to every situation? This is exactly how cargo cult mentality spreads. This has nothing to do with a defining a service API boundary or ServiceStack. I've already provided a link to actual implementation issues for using interfaces across process boundaries and how it violates the core tenants of a service - feel free to ignore it and follow alternative advice on the Internet you think is more relevant and specific to your use-case. – mythz Aug 06 '13 at 03:09
  • The implementation issue you talk about in your link doesn't apply here: when you specify IEnumerable as the return type, no type information needs to be passed in Json. It would be bloating the Json if the DTO used IReturn> or IReturn>.My problem with using Lists in public APIs is that it gives a false representation of the API: it suggests a client could Add or Remove from the result of a service call which would obviously only do so for the local collection. Just trying a to have a constructive discussion here. – Guy Godin Aug 06 '13 at 05:47

1 Answers1

1

ServiceStack wants you to encapsulate your responses inside its own class. So you would create a AllCustomerResponse class with a Customers IEnumerable property.

BrandonG
  • 876
  • 11
  • 20
  • That [used to be the case](http://stackoverflow.com/a/11750800/85785), now the [New API supports clean responses](https://github.com/ServiceStack/ServiceStack/wiki/New-Api). The problem is with using interfaces to define the service layer. – mythz Aug 05 '13 at 15:58
  • I have been using the new API but did not notice this change. Thanks! – BrandonG Aug 05 '13 at 18:09