3

MVCでcsvへのエクスポートを実装しています。
パラメータは日時型であるため、ユーザーの文化が異なるため、データをポストに送信する必要があります。

サーバーコード:

[HttpPost]
public async Task<FileResult> ExportBomTotal(ReportRequestVM reportRequestVM)
{
    List<MyData> result = await service.getData(reportRequestVM);
    string fileName = string.Format("file{0}-{1} .csv", reportRequestVM.StartDate.ToShortDateString(), reportRequestVM.EndDate.ToShortDateString());
    return new CSVResult<MyData>(result) { FileDownloadName = fileName };
}

クライアントでは、次のようにポストでデータを送信しようとしています:

$.ajax({
    url: '@Url.Action("ExportBomTotal", "Analytics")',
    type: 'POST',
    data: JSON.stringify(searchParameters),
    contentType: 'application/json',
    success: function (data) {
        debugger;
    //  window.location.assign(data);
    // window.location.replace(data);
    },
    error: function (response) {
        debugger;
    },
    cache: false
});

日付はサーバーに渡されます。これまでのところ問題ありませんが、ダウンロード ファイルのポップアップが表示されません。
window.location を使用する必要があると思いますが、リクエストはポスト操作である必要があります。

CSVResult をどのように求められたかについては、 public seal class CSVResult : FileResult where T : class { private readonly IEnumerable _collection;

    public CSVResult(IEnumerable<T> collection)
        : base("text/csv")
    {
        _collection = collection;
    }

    protected override void WriteFile(HttpResponseBase response)
    {
        Stream outputStream = response.OutputStream;
        using (MemoryStream mstream = new MemoryStream())
        {
            WriteObject(mstream);
            outputStream.Write(mstream.GetBuffer(), 0, (int)mstream.Length);
        }
    }

    private void WriteObject(Stream stream)
    {
        // We will follow the recommandations stated in this article
        // http://www.commentcamarche.net/faq/sujet-7273-exporter-a-coup-sur-du-csv
        StreamWriter writer = new StreamWriter(stream, System.Text.Encoding.Default);
        //modelType.
        Dictionary<string, bool> dict = new Dictionary<string, bool>();

        // Render columns
        Type modelType = typeof(T);
        PropertyInfo[] props = modelType.GetProperties();
        foreach (PropertyInfo prop in props)
        {
            object[] attrs = prop.GetCustomAttributes(true);
            foreach (VisibleAttribute visible in attrs.OfType<VisibleAttribute>())
            {
                dict.Add(prop.Name, visible.Hide);
            }
        }
        List<ModelMetadata> metadatas = ModelMetadataProviders.Current.GetMetadataForProperties(null, modelType)
            .Where(m => !dict.ContainsKey(m.PropertyName) || dict[m.PropertyName] )
                .OrderBy(p => p.Order).ToList();

        foreach (ModelMetadata t in metadatas)
        {
            WriteValue(writer, t.DisplayName ?? t.PropertyName);
        }

        writer.WriteLine();
        // Render data
        var en = _collection.GetEnumerator();
        while (en.MoveNext())
        {
            ModelMetadata mprop = ModelMetadataProviders.Current.GetMetadataForType(() => en.Current, modelType);

            var allowedProperties = mprop.Properties
                .Where(m => !dict.ContainsKey(m.PropertyName) || dict[m.PropertyName]);
            foreach (ModelMetadata prop in allowedProperties)
            {
                WriteValue(writer, prop.SimpleDisplayText ?? String.Empty);
            }
            writer.WriteLine();
        }
        writer.Flush();
    }
    /// <summary>
    /// Writes the value.
    /// </summary>
    /// <param name="writer">The writer.</param>
    /// <param name="literal">The literal.</param>
    private static void WriteValue(StreamWriter writer, String literal)
    {
        // Enclose values in quote
        writer.Write("\"");
        string line = literal;//.Replace("\"", "\"\"");
        writer.Write(line);
        writer.Write("\",");
    }
}

アドバイスをいただければ幸いです、
1o、
ロニー

4

2 に答える 2

0

しかし、ダウンロードファイルのポップアップが表示されません

それは正常です。AJAX を使用してファイルをダウンロードすることはできません。AJAX 要求の成功コールバックが実行され、データ引数として CSV 生成ファイルが渡されます。このファイルはクライアントで操作できますが、[名前を付けて保存] ダイアログでプロンプトを表示することはできません。

これを実現したい場合は、必要なパラメーターを含む標準の HTML フォームを提供する必要があります。このフォームの送信は、javascript を使用してトリガーできます。多くのパラメーターがない場合の代替手段として、コントローラー アクションを指す標準のアンカーを使用できます。

于 2013-05-13T15:31:34.603 に答える
0

これは不可能です。既に ajax 呼び出しで受信したデータをブラウザーにダウンロードさせることはできません。

本当にデータを投稿する必要がある場合は、javascript を含むフォームを送信して、ダウンロード アクションをトリガーすることができます。

get で十分な場合はlocation.href、ダウンロード アクションのリンクを割り当てるだけで済みます。

編集:フォームの例

@using (Html.BeginForm("ExportBomTotal", "Analytics") {

   ... render your searchparameters as html inputs

}

// submit the form with javascript:
$('form').submit();
于 2013-05-13T15:31:49.500 に答える