2017-08-16 1 views
-1

これに続いてgreat exampleというカスタムメディアタイプフォーマッタを実装することができました。これは、CSVが、それはMediaTypeFormatterで匿名のIEnumerable型を処理する

を訴えてType itemType = type.GetGenericArguments()[0];で失敗したとして、私は私がダウンロードしたい匿名JSONオブジェクトを(下)、持っている場合はインデックスは外だったが、このような商品等、アイテム、住所のタイプのための素晴らしい作品配列の境界。

助けていただければ幸いです。

var _list = _dt.AsEnumerable().Select(r => new 
{ 
    LkpColCode = r.Field<string>("lkp_column_code"), 
    LkpColName = r.Field<string>("Description") 
}); 

return _list; 

/* [{"lkpColCode":"BUS","lkpColName":"Bus"},{"lkpColCode":"COM","lkpColName":"Community Bus"}, 
    {lkpColCode":"STC","lkpColName":"Streetcar"},{"lkpColCode":"SUB","lkpColName":"Subway"}, 
    {"lkpColCode":"TRC","lkpColName":"Trolley Coach"}]*/ 

EDIT:その下の完全な作業コードは、匿名

以外の任意の種類を扱うことができ
public class CSVFormatter : MediaTypeFormatter 
    { 
     private string FileName { get; set; } 

     public CSVFormatter() 
     { 
      SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/csv")); 

      SupportedEncodings.Add(new UTF8Encoding(encoderShouldEmitUTF8Identifier: false)); 
      SupportedEncodings.Add(Encoding.GetEncoding("iso-8859-1")); 
     } 

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

      SupportedEncodings.Add(new UTF8Encoding(encoderShouldEmitUTF8Identifier: false)); 
      SupportedEncodings.Add(Encoding.GetEncoding("iso-8859-1")); 
     } 

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

      SupportedEncodings.Add(new UTF8Encoding(encoderShouldEmitUTF8Identifier: false)); 
      SupportedEncodings.Add(Encoding.GetEncoding("iso-8859-1")); 
     } 

     public override void SetDefaultContentHeaders(Type type, HttpContentHeaders headers, MediaTypeHeaderValue mediaType) 
     { 
      base.SetDefaultContentHeaders(type, headers, mediaType); 
      headers.Add("Content-Disposition", string.Format("attachment; filename={0}", FileName)); 
     } 

     public override MediaTypeFormatter GetPerRequestFormatterInstance(Type type, HttpRequestMessage request, MediaTypeHeaderValue mediaType) 
     { 
      //Usuage: In Controller Action: 
      //if (!Request.Properties.ContainsKey("filename")) 
      //Request.Properties.Add("filename", String.Format("SomeFileName_{0}.csv", DateTime.Now.ToString("yyyyMMdd-hhmmss"))); 

      if (request.Properties.ContainsKey("filename")) 
      { 
       FileName = request.Properties["filename"] as string; 
      } 
      else if (!String.IsNullOrWhiteSpace(FileName = request.GetQueryString("filename"))) 
      { 
       FileName = FileName.CustomCompare(".csv") ? FileName : FileName + ".csv"; 
      } 
      else 
      { 
       FileName = String.Format("Data-{0}.csv", DateTime.Now.ToString("yyyyMMdd-HHmmss")); 
      } 

      return this; 
     } 

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

      return isTypeOfIEnumerable(type); 
     } 

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

     public override bool CanReadType(Type type) 
     { 
      return false; 
     } 

     public override Task WriteToStreamAsync(Type type, object value, Stream stream, HttpContent content, TransportContext transportContext) 
     { 
      writeStream(type, value, stream, content); 
      var tcs = new TaskCompletionSource<int>(); 
      tcs.SetResult(0); 
      return tcs.Task; 
     } 

     private void writeStream(Type type, object value, Stream stream, HttpContent content) 
     { 
      //NOTE: We have check the type inside CanWriteType method. If request comes this far, the type is IEnumerable. We are safe. However it fails for Anonymous and errors out. 

      Encoding effectiveEncoding = SelectCharacterEncoding(content.Headers); 
      Type itemType = type.GetGenericArguments()[0]; 

      using (var writer = new StreamWriter(stream, effectiveEncoding)) 
      { 
       //Write out columns 
       writer.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) 
        { 
         var columnValue = Escape(val.Value); 
         _valueLine = string.Concat(_valueLine, columnValue, ","); 
        } 

        _valueLine = _valueLine.Substring(0, _valueLine.Length - 1); 
        writer.WriteLine(_valueLine); 
       } 
      } 
     } 

     #region Escape Characters 
     static char[] _specialChars = new char[] { ',', '\n', '\r', '"' }; 

     private string Escape(object o) 
     { 
      if (o == null) 
       return String.Empty; 

      string field = o.ToString(); 

      // Delimit the entire field with quotes and replace embedded quotes with "". 
      if (field.IndexOfAny(_specialChars) != -1) 
       return String.Format("\"{0}\"", field.Replace("\"", "\"\"")); 
      else return field; 

      //Quote forcefully 
      //return String.Format("\"{0}\"", field.Replace("\"", "\"\"")); 
     } 
     #endregion 
    } 
+0

_それは失敗します._どのように?より具体的にしてください。 –

+0

@MartinLiversage最新のコードをご覧ください。私はこのMedia Formatter内でAnonymous型を処理しようとしています。 – programmerboy

答えて

0

まずそれだけ匿名型だ、JSONはこれとは何の関係もありません。

第2に、使用しているサンプルは、データをフォーマットできるかどうかを調べるためにタイプを使用します。匿名型を使用している場合は、そのまま動作することはできません。

最も簡単なルートは

private void WriteItem(Thing thing, StreamWriter writer) 
{ 
    writer.WriteLine("{0},{1}", Escape(thing.LkpColCode), Escape(thing.LkpColName)); 
} 

がいることを与えるこのコードを

public class Thing 
{ 
    public string LkpColCode {get;set;} 
    public string LkpColName {get;set;} 
} 

新しいクラスを作成し、例からThingProductを変更(またはあなたがそれを呼び出す何でも)、その後、変更することです

行ってどこに行くかを見てください。より多くのヘルプが必要な場合は、おそらくより多くのコードで質問を更新したいでしょう。

+0

私の質問では、私のコードは既知の型を扱うことができるので、この解決法は正確には役に立たないと言いました。私は特に匿名型のデータを送信する必要があるため、匿名型を処理する方法があることを知りたいと思っています。更新された質問をご覧ください。 – programmerboy

関連する問題