MVC3 Ajax.BeginForm Post Download File

2019-08-01 03:49发布

问题:

 <div id="ProductionReport">
    <div class="ui-widget">
        @Using Ajax.BeginForm("Index", "Reports", ajaxOptions:=New AjaxOptions With {.InsertionMode = InsertionMode.Replace, .HttpMethod = "POST", .UpdateTargetId = "searchresultdata"}, htmlAttributes:=New With {.id = "productionform"})
            @Html.ValidationSummary(True)
            @<fieldset class="ui-widget-content">
                <legend class="ui-state-default">Production Report</legend>
                <div class="editor-label">
                    @Html.LabelFor(Function(model) model.ProductionReportData.FromDate, "From Date: ")
                    @Html.Raw(" ")
                    @Html.TextBoxFor(Function(model) model.ProductionReportData.FromDate, New With {.class = "ui-state-default", .id = "datepicker", .Style = "font-size:x-small;", .name = "fromdate"})
                    @Html.ValidationMessageFor(Function(model) model.ProductionReportData.FromDate)
                </div>
                <div class="editor-label">
                    @Html.LabelFor(Function(model) model.ProductionReportData.ToDate, "To Date: ")
                    @Html.Raw(" ")
                    @Html.TextBoxFor(Function(model) model.ProductionReportData.ToDate, New With {.class = "ui-state-default", .id = "datepicker2"})
                    @Html.ValidationMessageFor(Function(model) model.ProductionReportData.ToDate)
                </div>
                <div class="editor-label">
                    @Html.LabelFor(Function(model) model.ProductionReportData.ShowDetails, "Show Details: ")
                    @Html.EditorFor(Function(model) model.ProductionReportData.ShowDetails)
                </div>
                <div class="editor-label">
                    <input class="ui-button ui-button-text-only ui-widget ui-state-default ui-corner-all"
                        type="submit" value="Search" name="btnSearch" />
                    <input class="ui-button ui-button-text-only ui-widget ui-state-default ui-corner-all"
                        type="submit" value="Export Data" name="btnSearch" />
                </div>
            </fieldset>
        End Using
    </div>
    <div id="searchresultdata" class="ui-widget-content">
    </div>
</div>

enter code h<HttpPost()> _
    Function ExportProductionReportData(ByVal data As ReportsModel) As FileResult


        Dim var = From I In db.scll_label Join P In db.pt_mstr On I.scll_part Equals P.pt_part _
                  Join C In db.sclws_cfg On I.scll_wsid Equals C.sclws_id _
                  Where P.pt_domain = "mueller" And C.sclws_domain = "mueller" _
                  And I.scll_transactiondate >= data.ProductionReportData.FromDate And I.scll_transactiondate <= data.ProductionReportData.ToDate _
                  Select I, P.pt_length, P.pt_net_wt, P.pt_desc1, P.pt_tol_high, P.pt_part_type, P.pt_um, _
                  C.sclws_proj_code, C.sclws_site

        Dim ProMod As New ProductionReportModel
        ProMod.ProductionDetails = New ObservableCollection(Of ProductionReportDetails)
        ProMod.ProductionGrandTotal = New ProductionReportGrandTotals
        ProMod.ProductionPartTotals = New ObservableCollection(Of ProductionReportTotalsByPart)


        ''Generate Production Details
        For Each rec In var

            Dim proModDtls As New ProductionReportDetails

            proModDtls.Customer = rec.I.scll_cust
            proModDtls.Feet = rec.I.scll_total_feet
            proModDtls.GrossWeight = rec.I.scll_weight
            proModDtls.NetWeight = rec.I.scll_weight - rec.I.scll_total_tare
            proModDtls.Part = rec.I.scll_part

            If rec.pt_um = "LB" Then
                Try
                    proModDtls.Pieces = rec.I.scll_total_feet / rec.pt_length
                Catch ex As Exception
                    proModDtls.Pieces = rec.I.scll_qty
                End Try
            ElseIf rec.pt_um = "FT" Then
                Try
                    proModDtls.Pieces = rec.I.scll_qty / rec.pt_length
                Catch ex As Exception
                    proModDtls.Pieces = rec.I.scll_qty
                End Try
            Else
                proModDtls.Pieces = rec.I.scll_qty
            End If

            proModDtls.Quantity = rec.I.scll_qty

            proModDtls.ReasonCode = rec.sclws_proj_code

            proModDtls.StandardWeight = rec.I.scll_std_weight

            proModDtls.Station = rec.I.scll_wsid

            proModDtls.Tare = rec.I.scll_total_tare

            proModDtls.TareDetail = rec.I.scll_tare_detail

            proModDtls.Ticket = rec.I.scll_ticket

            Try
                proModDtls.DrawingEfficiency = ((rec.I.scll_weight - rec.I.scll_total_tare) / rec.I.scll_std_weight) * 100

            Catch ex As Exception

            End Try

            proModDtls.TicketDate = rec.I.scll_transactiondate

            ProMod.ProductionDetails.Add(proModDtls)

        Next
        Dim csvCreator As New CSVFileMaker(Of ProductionReportDetails, List(Of ProductionReportDetails))
        csvCreator.data = ProMod.ProductionDetails.ToList
        Dim csvdata As String = csvCreator.GenerateCSVFile
        Dim d = Encoding.ASCII.GetBytes(csvdata)
        Dim filename As String = "ProductionReport" & Date.Now.Year.ToString & "_" & Date.Now.Month.ToString & "_" & Date.Now.Day & ".csv"
        Dim cd = New System.Net.Mime.ContentDisposition With {.FileName = filename, .Inline = False, .DispositionType = "attachment"}
        Response.AppendHeader("Content-Disposition", cd.ToString)
        Return File(d, "text/csv", filename)




    End Function

' GET: /Reports _ Function Index(ByVal btnSearch As String, ByVal data As ReportsModel) As ActionResult

        data.DrawingEfficiencyWeeklyData = New DrawingEfficiencyWeeklyData
        data.DrawingEfficiencyPeriodData = New DrawingEfficiencyPeriodData
        data.DrawingEfficiencyYearlyData = New DrawingEfficiencyYearlyData
        data.DrawingEfficiencyYearlyMeanData = New DrawingEfficiencyYearlyMeanData
        data.DrawingEfficiencySummaryData = New DrawingEfficiencySummaryData
        data.ToleranceOverrideReportData = New ToleranceOverrideReportData
        data.TareDetailReportData = New TareDetailReportData

        Dim var = db.GetGLCYears
        Dim var2 = db.GetGLCYears
        Dim var3 = db.GetGLCYears
        Dim var4 = db.GetGLCYears

        Dim allList As New SelectListItem With {.Value = 0, .Text = "All"}
        Dim BonusList As New SelectListItem With {.Value = 1, .Text = "Bonus"}
        Dim OtherList As New SelectListItem With {.Value = 2, .Text = "Other"}

        Dim categoryList As New List(Of SelectListItem)
        categoryList.Add(allList)
        categoryList.Add(BonusList)
        categoryList.Add(OtherList)

        data.DrawingEfficiencyYearlyMeanData.CategoryList = categoryList
        data.DrawingEfficiencyYearlyMeanData.YearList = var4.Select(Function(i) New SelectListItem With {.Value = i.Y, .Text = i.Y})
        data.DrawingEfficiencyWeeklyData.YearList = var.Select(Function(i) New SelectListItem With {.Value = i.Y, .Text = i.Y})
        data.DrawingEfficiencyPeriodData.YearList = var2.Select(Function(i) New SelectListItem With {.Value = i.Y, .Text = i.Y})
        data.DrawingEfficiencyYearlyData.YearList = var3.Select(Function(i) New SelectListItem With {.Value = i.Y, .Text = i.Y})

        Select Case btnSearch

            Case Is = "Search"
                Return (SearchProductionReport(data))
            Case Is = "Export Data"
                Return ExportProductionReportData(data)
            Case Else
                Return View(data)
        End Select

        Return View(data)
    End Function

Basically my form sends the ajax response to div which holds a partial view but I have another submit button that uses the same data to generate a csv file. I cannot get this file to download it simply outputs it into the div. can anyone help or guide the right direction.. I have tried actionlinks but it will never persist my model to the database i can't use html.beginforms because i can't set a target div to load the partial view into.

Update: using script but still not working

 <script type="text/javascript">
$(document).ready(function () {
    $("#productionsearch").click(function () {
        $("#productionform").submit(function () {
            $.ajax({
                url: this.action,
                type: this.action,
                data: $(this).serialize(),
                success: function (result) {
                $("#searchresultdata").html(result);
                }
            });
        });
    });
});

`

回答1:

You cannot use AJAX to download files. Just use a normal Html.BeginForm.



回答2:

<script type="text/javascript">
$(document).ready(function () {
    $("#ProductionSearch").click(function () {
        alert("Button Clicked");
        var $form = $("#ProductionSearch").parents('form')
        $.ajax({
            type: "POST",
            url: "@URL.Action("SearchProductionReport")",
            data: $form.serialize(),
            error: function (xhr, status, error) {
                alert("an error occurred" + error)
            },
            success: function (response) {
                alert("Function worked");
                $("#searchresultdata").html(response);
            }
        });
    });
});

Answer. I figured it out. Use an HTML.BeginForm("YourDownloadAction","YourController","id of form") then create two button one with type=submit and the other with type being button. make sure you javascript is calling the action that doesn't require downloading files. and that's it. Now you have to implement validation since it won't be implemented on the ajax call through jquery... Thanks Darin you pointed me in the right direction at least.

Updated for validation

<script type="text/javascript">
$(document).ready(function () {
    $("#ProductionSearch").click(function () {
      var $form = $("#ProductionSearch").parents('form')
      if ($($form).validate().form() == true) {
       $.ajax({
            type: "POST",
            url: "@Url.Action("SearchProductionReport", "Reports", Nothing)",
            data: $form.serialize(),
            error: function (xhr, status, error) {
              $("#dialog").dialog("open");
              $("#dialog").html("<p>Please be advised that an error has occured while searching production data please try again or contact your administrator</p> " +"<br>" + error + "</br>");
            },
            success: function (response) {
                $("#searchresultdata").html(response);
            }
        });
      }
    });
});