Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Merge pull request WebApiContrib#48 from tugberkugurlu/tugberk
added CSVMediaTypeFormatter
  • Loading branch information
darrelmiller committed Apr 10, 2012
2 parents 91ea519 + d547a72 commit 4b5a7a6
Show file tree
Hide file tree
Showing 2 changed files with 122 additions and 0 deletions.
121 changes: 121 additions & 0 deletions src/WebApiContrib/Formatting/CSVMediaTypeFormatter.cs
@@ -0,0 +1,121 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Http.Formatting;
using System.Net.Http.Headers;
using System.Collections;
using System.IO;
using System.Net;
using System.Threading.Tasks;

namespace WebApiContrib.Formatting {

public class CSVMediaTypeFormatter : MediaTypeFormatter
{
public CSVMediaTypeFormatter()
{
SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/csv"));
}

public CSVMediaTypeFormatter(MediaTypeMapping mediaTypeMapping) : this()
{
MediaTypeMappings.Add(mediaTypeMapping);
}

public CSVMediaTypeFormatter(IEnumerable<MediaTypeMapping> mediaTypeMappings) : this()
{
foreach (var mediaTypeMapping in mediaTypeMappings)
MediaTypeMappings.Add(mediaTypeMapping);
}

protected override bool CanWriteType(Type type)
{
if (type == null)
throw new ArgumentNullException("type");

return isTypeOfIEnumerable(type);
}

protected override Task OnWriteToStreamAsync(
Type type,
object value,
Stream stream,
HttpContentHeaders contentHeaders,
FormatterContext formatterContext,
TransportContext transportContext) {

return Task.Factory.StartNew(() => {
writeStream(type, value, stream, contentHeaders);
});
}

//private utils

private void writeStream(Type type, object value, Stream stream, HttpContentHeaders contentHeaders)
{
//NOTE: We have check the type inside CanWriteType method
//If request comes this far, the type is IEnumerable. We are safe.

Type itemType = type.GetGenericArguments()[0];

StringWriter _stringWriter = new StringWriter();

_stringWriter.WriteLine(
string.Join<string>(
",", itemType.GetProperties().Select(x => x.Name )
)
);

foreach (var obj in (IEnumerable<object>)value)
{
var vals = obj.GetType().GetProperties().Select(
pi => new {
Value = pi.GetValue(obj, null)
}
);

string _valueLine = string.Empty;

foreach (var val in vals)
{
if (val.Value != null)
{
var _val = val.Value.ToString();

//Check if the value contans a comma and place it in quotes if so
if (_val.Contains(","))
_val = string.Concat("\"", _val, "\"");

//Replace any \r or \n special characters from a new line with a space
if (_val.Contains("\r"))
_val = _val.Replace("\r", " ");
if (_val.Contains("\n"))
_val = _val.Replace("\n", " ");

_valueLine = string.Concat(_valueLine, _val, ",");

}
else
{
_valueLine = string.Concat(string.Empty, ",");
}
}

_stringWriter.WriteLine(_valueLine.TrimEnd(','));
}

var streamWriter = new StreamWriter(stream);
streamWriter.Write(_stringWriter.ToString());
}

private bool isTypeOfIEnumerable(Type type)
{
foreach (Type interfaceType in type.GetInterfaces())
if (interfaceType == typeof(IEnumerable))
return true;

return false;
}
}
}
1 change: 1 addition & 0 deletions src/WebApiContrib/WebApiContrib.csproj
Expand Up @@ -65,6 +65,7 @@
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="Formatting\CSVMediaTypeFormatter.cs" />
<Compile Include="Formatting\JsonpFormatter.cs" />
<Compile Include="Internal\MediaTypeConstants.cs" />
<Compile Include="Conneg\ContentNegotiation.cs" />
Expand Down

0 comments on commit 4b5a7a6

Please sign in to comment.