Skip to content

Instantly share code, notes, and snippets.

@scottmcarthur
Created February 9, 2014 12:23
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save scottmcarthur/8898358 to your computer and use it in GitHub Desktop.
Save scottmcarthur/8898358 to your computer and use it in GitHub Desktop.
Transparent encoding/decoding Id properties in ServiceStack v4
using System;
using ServiceStack;
using System.Text;
using ServiceStack.Web;
namespace ComplexIdTest
{
class MainClass
{
public static void Main()
{
// Very basic console host
var appHost = new AppHost(500);
appHost.Init();
appHost.Start("http://*:8081/");
Console.ReadKey();
}
}
public class AppHost : AppHostHttpListenerPoolBase
{
public AppHost(int poolSize) : base("Complex Id Test Service", poolSize, typeof(ComplexIdTestService).Assembly) {}
public override void Configure(Funq.Container container)
{
Config = new HostConfig {
DebugMode = true,
};
}
}
[UsesEncodedAttribute]
[Route("/Object/{Id}","GET")]
public class GetObjectWithComplexIdRequest : IReturn<ObjectWithComplexIdResponse>
{
[EncodedId]
public string Id { get; set; }
}
[UsesEncodedAttribute]
public class ObjectWithComplexIdResponse
{
[EncodedId]
public string Id { get; set; }
}
public class ComplexIdTestService : Service
{
public ObjectWithComplexIdResponse Get(GetObjectWithComplexIdRequest request)
{
Console.WriteLine("The requested id is {0}", request.Id);
return new ObjectWithComplexIdResponse { Id = request.Id };
}
}
public class EncodedIdAttribute : Attribute
{
}
public class UsesEncodedAttribute : Attribute, IHasRequestFilter, IHasResponseFilter
{
IHasRequestFilter IHasRequestFilter.Copy()
{
return this;
}
IHasResponseFilter IHasResponseFilter.Copy()
{
return this;
}
public void RequestFilter(IRequest req, IResponse res, object requestDto)
{
// Decode the properties on the requestDto having the EncodedId attribute
var type = requestDto.GetType();
var properties = type.GetPublicProperties();
foreach(var p in properties)
{
// Find the property marked with EncodedId that is of type string, that can be read and written to
if(!p.HasAttribute<EncodedIdAttribute>() || p.PropertyType != typeof(string) || !p.CanRead || !p.CanWrite)
continue;
// Get the encoded value
string encodedValue = p.GetValue(requestDto, null) as string;
if(encodedValue != null)
{
// Decode the value from base64
string decodedValue = Encoding.UTF8.GetString(Convert.FromBase64String(encodedValue));
// Set the value to decoded string
p.SetValue(requestDto, decodedValue, null);
}
}
}
public void ResponseFilter(IRequest req, IResponse res, object response)
{
// Encode properties on the response having the EncodedId attribute
var type = response.GetType();
var properties = type.GetPublicProperties();
foreach(var p in properties)
{
// Find the property marked with EncodedId that is of type string, that can be read and written to
if(!p.HasAttribute<EncodedIdAttribute>() || p.PropertyType != typeof(string) || !p.CanRead || !p.CanWrite)
continue;
// Get the decoded value
string decodedValue = p.GetValue(response, null) as string;
if(decodedValue != null)
{
// Encode the value to base64
string encodedValue = Convert.ToBase64String(decodedValue.ToUtf8Bytes());
// Set the value to decoded string
p.SetValue(response, encodedValue, null);
}
}
}
public int Priority { get { return int.MinValue; } }
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment