最近(2)同様の状況があり、ajax経由でそれを行うには実際の焼き焼き方法がないことがわかりました。良いニュース:それは実際には本当に簡単で、あなたはajaxコールが必要ありません。
あなたができることは、フォームの投稿要求を送信することです。コントローラーのポストアクションでファイルをメモリに生成し、ビューの再読み込みを行わずにファイルを返すために "return File()"を使用します。ここ
はiTextSharpを使用した例である。
例モデル:
public class TestM
{
public string FirstName { get; set; }
public string LastName { get; set; }
public int Number { get; set; }
}
ビュー(基本自動作成生成)
@model DeleteMeWeb45.Models.TestM
@{
ViewBag.Title = "Index";
}
<h2>Index</h2>
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>TestM</h4>
<hr />
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
<div class="form-group">
@Html.LabelFor(model => model.FirstName, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.FirstName, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.FirstName, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.LastName, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.LastName, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.LastName, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Number, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Number, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Number, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
コントローラー:で
public ActionResult Index()
{
TestM t = new TestM();
return View(t);
}
[HttpPost]
public ActionResult Index(TestM t)
{
if(ModelState.IsValid)
{
Document doc = new Document(iTextSharp.text.PageSize.LETTER, 10, 10, 42, 30);
byte[] pdfBytes;
BaseFont bfTimes = BaseFont.CreateFont(BaseFont.TIMES_ROMAN, BaseFont.CP1252, false);
Font timesBold = new Font(bfTimes, 12, Font.BOLD);
using (var mem = new MemoryStream())
{
PdfWriter wri = PdfWriter.GetInstance(doc, mem);
doc.SetMargins(20, 20, 20, 60);
doc.Open();
var orderInfoTable = new PdfPTable(2);
orderInfoTable.AddCell(new Phrase("First Name:", timesBold));
orderInfoTable.AddCell(new Phrase(t.FirstName, timesBold));
orderInfoTable.AddCell(new Phrase("Last Name:", timesBold));
orderInfoTable.AddCell(new Phrase(t.LastName, timesBold));
orderInfoTable.AddCell(new Phrase("Number:", timesBold));
orderInfoTable.AddCell(new Phrase(t.Number.ToString(), timesBold));
doc.Add(orderInfoTable);
doc.Close();
pdfBytes = mem.ToArray();
}
return File(pdfBytes, "application/pdf", "Weeeeeee_" + DateTime.Now.ToString("_MM-dd-yyyy-mm-ss-tt") + ".pdf");
}
else
{
return View(t);
}
}
ev
ビュー:
変更1あなたがあるとして、ボタンを提出する(それが保存または何でもありません)と、ちょうどあなたのような上記の例を修正するだろうダウンロード余分なボタンが欲しいあなたのフォームを維持したいENT 。
@using (Html.BeginForm("Index", "Home", FormMethod.Post, new { id = "transferForm" }))
変更2.別の場所でフォームを送信するボタンやJSを追加します:
<div class="row">
<div class="btn btn-primaryDark btn-sm" id="btnRunReport" style="min-width:120px;">Run Report</div>
</div>
@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
<script>
$(document).ready(function() {
$("#btnRunReport").click(function() {
$('#transferForm').attr('action', "/Home/JSFUN").submit();
});
});
</script>
}
コントローラーの変更:をフォームにIDを与えます1. POSTリクエストを処理するための新しいコントローラのアクションを作成します。
[HttpPost]
public ActionResult JSFUN(TestM t)
{
Document doc = new Document(iTextSharp.text.PageSize.LETTER, 10, 10, 42, 30);
byte[] pdfBytes;
BaseFont bfTimes = BaseFont.CreateFont(BaseFont.TIMES_ROMAN, BaseFont.CP1252, false);
Font timesBold = new Font(bfTimes, 12, Font.BOLD);
using (var mem = new MemoryStream())
{
PdfWriter wri = PdfWriter.GetInstance(doc, mem);
doc.SetMargins(20, 20, 20, 60);
doc.Open();
var orderInfoTable = new PdfPTable(2);
orderInfoTable.AddCell(new Phrase("First Name:", timesBold));
orderInfoTable.AddCell(new Phrase(t.FirstName, timesBold));
orderInfoTable.AddCell(new Phrase("Last Name:", timesBold));
orderInfoTable.AddCell(new Phrase(t.LastName, timesBold));
orderInfoTable.AddCell(new Phrase("Number:", timesBold));
orderInfoTable.AddCell(new Phrase(t.Number.ToString(), timesBold));
doc.Add(orderInfoTable);
doc.Close();
pdfBytes = mem.ToArray();
}
return File(pdfBytes, "application/pdf", "Weeeeeee_" + DateTime.Now.ToString("_MM-dd-yyyy-mm-ss-tt") + ".pdf");
}
ユーザーがフォームを使用することができます。この方法では、ボタンと異なる目的のためにエクスポートボタンを提出します。
AJAX経由で直接ダウンロードすることはできません。 – SLaks
なぜあなたはAJAXコールでこれを行う必要があると思いますか?ユーザーをURLに誘導するだけです。ファイルがダウンロードされると、表示されたページは変更されません。 – DavidG
AJAXなしでやりたいことを達成する別の実装がありますか?これまでのところ、AJAXはC#コントローラにカスタムオブジェクトを渡す唯一の方法でした – slugibihl