Hi Demis,
So I decided to look into the guts of ServiceStack to see how things
were put together and find out if there was a way to solve my use
case. The use case is to get the Content from a request into a DTO for
further processing.I found a solution, though I totally understand
that it goes against the metality of ServiceStack and that you may
want to throw eggs or tomatoes my way. ;)
Then again, if I had this issue, others might as well, and well maybe
you won't hate my approach all together. (he cringes as he types) :)
In my case, I did not care to create a DTO with all of the
XmlSerializer junk. It served no purpose in this case, I decided it
was more useful to get the Raw Content from the httpRequest and go
from there. Below is what I did. I'll gladly submit it to GitHub,
though I imagine you will have some say on this, and that is perfectly
cool. :) This is working beautifully for me and I think it fits ok
within the framework, not perfect, but possibly useful.
I created a new interface called IRestGetRawContentStream. For now I
added it to the ServiceStack.Interfaces ServiceHost folder. It looks
like this:
public interface IRestGetRawContentStream
{
Stream RawContent { get; set; }
}
I then implemented a new DTO that just had my Rest parameters and
RawContent.
Then I went to ServiceStack.WebHost.Endpoints.RestHandler and I
modified GetRequest to manage the new interface. Here is what mine
looks like right now.
private static object GetRequest(IHttpRequest httpReq, IRestPath
restPath)
{
var requestParams = httpReq.GetRequestParams();
object requestDto = null;
if (!string.IsNullOrEmpty(httpReq.ContentType) &&
httpReq.ContentLength > 0)
{
var requestDeserializer =
EndpointHost.AppHost.ContentTypeFilters.GetStreamDeserializer(httpReq.ContentType);
if (requestDeserializer != null)
{
try
{
requestDto = requestDeserializer(restPath.RequestType,
httpReq.InputStream);
}
catch (Exception ex)
{
if
(typeof(IRestGetRawContentStream).IsAssignableFrom(restPath.RequestType))
{
IRestGetRawContentStream holder =
(IRestGetRawContentStream)Activator.CreateInstance(restPath.RequestType);
httpReq.InputStream.Position = 0;
if (holder.RawContent == null)
{
holder.RawContent = new MemoryStream();
}
httpReq.InputStream.CopyTo(holder.RawContent);
holder.RawContent.Position = 0;
requestDto = holder;
}
else
{
throw ex;
}
}
}
}
return restPath.CreateRequest(httpReq.PathInfo, requestParams,
requestDto);
}
My mentality... I needed the raw content and this was the shortest
route I could find to getting it without modifying more than one
method. I don't normally like to rely on errors to implement something
but I also did not want to mess with the innards of ServiceStack and
break something this important. I also did not want to take the
IsAssignableFrom hit for every call. This is an Edge Use Case and so
it seemed better to handle it as an error, normally, in this situation
you just get a 500 error. This way the performance hit only occurs for
the edge case. I chose an interface, as opposed to an attribute, so
there would be a certain place to put the contents.
I am open to pretty much any discussion that would serve this use
case.
Your thoughts, comments, ideas, improvements, virtual tomatoes, etc
are ...
Best,
\ ^ / i l l
That's it! Again, this is working beautifully for me. I need to now
test against Android devices to make sure everything is ok but so far
my Tests all pass. I'm using a Console app to test my service
implementation.
On Oct 10, 9:40 pm, Demis Bellot <
demis.bel...@gmail.com> wrote:
> So basically if you want an XmlSerializer that will support attributes
> you'll likely need to use XmlSerializer and decorate your DTO's accordingly:
http://msdn.microsoft.com/en-us/library/system.xml.serialization.xmls...
> > >
http://twitter.com/demisbellothttp://www.servicestack.net/mythz_blog-...quoted text -