Skip to content

Instantly share code, notes, and snippets.

@raghur
Last active December 19, 2015 00:29
Show Gist options
  • Save raghur/5868913 to your computer and use it in GitHub Desktop.
Save raghur/5868913 to your computer and use it in GitHub Desktop.
Handling POST data from Chargify so that MVC model binding works...
/// <summary>
/// Filter that replaces [] with . so that model binding works.
/// </summary>
/// <remarks>
/// simplistic - does a global replace. Also assumes that [, ]
/// are not url encoded in the key names (and this is
/// the case with chargify right now
/// so product name like 'Daily Plan []' is sent as
/// payload[subscription][product][name]=Daily%20Plan%20%5B%5D
/// ie key names square brackets are sent as is, whereas in values they are url encoded.
///
///
/// This filter does not handle arrays - but no chargify event has arrays.
///
/// attached to the Request.Filter in Global.asax for chargify events.
/// </remarks>
public class ChargifyStreamDecorator : Stream
{
private readonly Stream theStream;
private Stream modifiedStream = null;
private string documentContents;
public ChargifyStreamDecorator(Stream orig)
{
this.theStream = orig;
}
public String OriginalContent
{
get
{
initialize();
return this.documentContents;
}
}
public override void Flush()
{
modifiedStream.Flush();
}
private void initialize()
{
// found that I cannot call this from the ctor since the actual stream return 0 length
// so calling this from read with the guard below
if (this.modifiedStream != null) return;
string documentContents;
using (Stream receiveStream = theStream)
{
using (StreamReader readStream = new StreamReader(receiveStream, Encoding.UTF8))
{
documentContents = readStream.ReadToEnd();
}
}
// [ -> ., ] -> ""
var modifiedContents = documentContents
.Replace("[", ".").Replace("]", "");
modifiedStream = new MemoryStream(Encoding.UTF8.GetBytes(modifiedContents));
}
public override long Seek(long offset, SeekOrigin origin)
{
return modifiedStream.Seek(offset, origin);
}
public override void SetLength(long value)
{
throw new NotSupportedException();
}
public override int Read(byte[] buffer, int offset, int count)
{
initialize();
return modifiedStream.Read(buffer, offset, count);
}
public override void Write(byte[] buffer, int offset, int count)
{
throw new NotSupportedException();
}
public override bool CanRead
{
get { return theStream.CanRead; }
}
public override bool CanSeek
{
get { return theStream.CanSeek; }
}
public override bool CanWrite
{
get { return theStream.CanWrite; }
}
public override long Length
{
get { return this.modifiedStream.Length; }
}
public override long Position { get { return this.modifiedStream.Position; } set { this.modifiedStream.Position = value; } }
}
public class WebApiApplication : System.Web.HttpApplication
{
public void Application_BeginRequest()
{
if (Request.Url.AbsolutePath.Contains("ChargifyEvents"))
{
Request.Filter = new ChargifyStreamDecorator(Request.Filter);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment