2012-10-25 15 views
11

Ben dinamik olarak oluşturulmuş bir dosyayı indiren bir denetleyici eylem var dowloadedYönlendirme/gösteri görünümü

public class MyClass 
    { 
     public string MyString { get; set; } 
     public int MyInt { get; set; } 
    } 

Bu çalışıyor ve dosya (myfile.xml) indirildi.
Ancak mesaj "indirildi" tarayıcıya gönderilmez. Benzer şekilde

, ben return Redirect("www.something.com");
için return Content("Downloaded");
ardından tarayıcı dosya indirme önce yönlendirilir değiştirirseniz. Önceden amble biraz itibariyle

, kullanıcı yolculuktur:

  • Kullanıcı
  • Formu
  • XML oluşturulur
  • gönderildiğinde önceki görünümde formu doldurduğu ve
  • Kullanıcı olduğunu indirilen yönlendirilen/"indirildi" görünümü gösterilmektedir (çok isabet F5 yeniden post olmaz bir şekilde)

cevap

7

Her bir HTTP isteğinin yalnızca bir yanıtı olabilir - ikiye gizlice girmeye çalışıyorsunuz (dosya ve sayfa).

Normalde bir gönderirken "Content-Disposition: eki" HTTP tarayıcı geçerli sayfada kalacak başlık ve bir dosya iletişim kaydedin (veya otomatik olarak indirme dosyayı kaydedin) pop. Formun tekrar gönderdikten önlemek istiyorsanız

Sen stratejisini değiştirmek zorunda olacak. Formun gönder düğmesini devre dışı bırakmak ve "Tamamlandı" mesajını div divdesinde göstermek için biraz javascript öneririm. Ross belirttiği gibi

9

, yalnızca HTTP isteğine bir yanıt döndürebilir. Ben bu durumda ne yapıyoruz geçerli:

  1. sunucuya sunucu bazı sunucu tarafı veri yapısında dosyası ve depolar üretir
  2. (Önbellek, Usersession, TempData)
  3. sunucu için istek gönder bir RedirectToAction() (POST, GET, desen YÖNLENDİRME)
  4. yönlendirildi eylem
  5. göndermek bir özel indirme eylemine window.location.href özelliğini ayarlayarak Önceden Oluşturulan dosyanın indirilmesini tetikler bazı javascript ile Görünüm döndürür döndürür İşte Dosya indirildikten sonra yönlendirildi nasıl tarayıcıya geri
5

dosyayı s. Ana mantık, dosya indirilene kadar yönlendirmeyi beklemektir. Bunu yapmak için, sunucu tarafı yanıtı hesaplanır ve yönlendirme, sunucu tarafı yanıt süresi + bazı ofset kullanılarak geciktirilir.

Sunucu Tarafı Kontrolörü Kodu:

[HttpPost] 
public ActionResult GetTemplate() 
    { 
     return Json(new {Url = Url.Action("ReturnTemplate") }); 
    } 

[HttpGet] 
public ActionResult ReturnTemplate() 
    { 
     FileResult fileResult = // your file path ; 
     return fileResult; 
    } 

İstemci Tarafı Kodu:

<div id="btnGen" align="right"><button class="main-button"  id="generateTemplate" type="Submit"></div> 

JavaScript:

$("#generateTemplate").click(function() { 
    var startTime = (new Date()).getTime(), endTime; 

     $.ajax({ 
      url: '@Url.Action("GetTemplate", "Controller")', 
      type: 'POST', 
      traditional: true, 
      dataType: "json", 
      contentType: "application/json", 
      cache: false, 
      data: JSON.stringify(), 
      success: function (result) { 
       endTime = (new Date()).getTime(); 
       var serverResponseTime = endTime - startTime + 500; 
       setInterval(function() { Back() }, serverResponseTime); 
       window.location = result.Url; 
      } 
     }); 
}); 

function Back() { 
    window.location = '@Url.Action("Index","Controller")'; 
} 
İlgili konular