2013-05-13 3 views
3

Я реализую экспорт в csv в MVC.
Поскольку параметры являются типами даты и времени, мне нужно отправить данные в сообщении из-за разных культур.получение файла с сервера

код сервера:

[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 общественной запечатан класс CSVResult: FileResult где T: класс { частных чтения 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("\","); 
    } 
} 

Любые советы будут оценены,
1о,
Рони

+0

Не могли бы вы показать нам класс CSVResult? – Kenneth

+0

Какую версию MVC вы используете? –

+0

Файл длинный, но идея использования отражения на типе и печать его в потоке. – ron

ответ

0

Это невозможно. Вы не можете заставить браузер загрузить данные, которые вы получили по вызову ajax.

Если вам действительно нужно опубликовать данные, вы можете отправить форму с помощью javascript для запуска действия загрузки.

Если получение достаточное, вы можете просто назначить location.href ссылкой на свое действие загрузки.

EDIT: Форма пример

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

    ... render your searchparameters as html inputs 

} 

// submit the form with javascript: 
$('form').submit(); 
+0

Спасибо Jan за ваш быстрый повтор, но как вы можете использовать location.href в пост-операции? – ron

+0

@ron так же, как вы бы в форме submit. 'location.href = targetlocation'. ваша служба должна будет вернуть значение «targetlocation», то есть ваш файл должен быть доступен через URL-адрес GET. –

+0

благодарит Кевина Б, но проблема в том, что действие требуется для работы в порту. потому что клиент передает дату и время. – ron

0

, но я не могу получить загружаемый файл Popup

Это нормально. Вы не можете использовать AJAX для загрузки файлов. Успешный вызов вашего запроса AJAX будет выполнен и передан в качестве аргумента данных CSV-сгенерированный файл, который вы могли бы манипулировать на клиенте, но вы не можете запросить какие-либо диалоговые окна «Сохранить как».

Если вы хотите достичь этого, вы должны предоставить стандартную HTML-форму, содержащую требуемые параметры, представление которых вы можете запустить с помощью javascript. В качестве альтернативы, если у вас нет многих параметров, вы можете использовать стандартный якорь, указывающий на действие контроллера.

Смежные вопросы