2

When the user clicks on an Html.ActionLink, I need to call a controller method that will download a csv report for the user. I also need to pass this controller the values from two input boxes that will denote a start and end date range they're looking for.

Currently I can assign the Html.ActionLink parameters using jQuery, however they are not making it back to the controller. Both parameters in the controller method are instantiated with null values.

I also cannot use a form/submit method as that is already being used on this particular form to allow the users to see the data in the date range requested before exporting to the csv.

jQuery

$(document).ready(function() {
    $('#startDate').change(function () {
        $('a').attr('start', $(this).val());
    });

    $('#endDate').change(function () {
        $('a').attr('end', $(this).val());
    });
});

ASP MVC 3 View

@using (Html.BeginForm())
{
    <div id="searchBox">
        @Html.TextBox("startDate", ViewBag.StartDate as string, new { placeholder = "   Start Date" })
        @Html.TextBox("endDate", ViewBag.EndDate as string, new { placeholder = "   End Date" })
        <input type="image" src="@Url.Content("~/Content/Images/Search.bmp")" alt="Search"  id="seachImage"/>
        <a href="#" style="padding-left: 30px;"></a>
    </div>
    <br />
    @Html.ActionLink("Export to Spreadsheet", "ExportToCsv", new { start = "" , end = ""} )
    <span class="error">
        @ViewBag.ErrorMessage
    </span>
}

Controller Method

    public void ExportToCsv(string start, string end)
    {

        var grid = new System.Web.UI.WebControls.GridView();

        var banks = (from b in db.AgentTransmission
                    where b.RecordStatus.Equals("C") &&
                          b.WelcomeLetter
                    select b)
                    .AsEnumerable()
                    .Select(x => new
                               {
                                   LastName = x.LastName,
                                   FirstName = x.FirstName,
                                   MiddleInitial = x.MiddleInitial,
                                   EffectiveDate = x.EffectiveDate,
                                   Status = x.displayStatus,
                                   Email = x.Email,
                                   Address1 = x.LocationStreet1,
                                   Address2 = x.LocationStreet2,
                                   City = x.LocationCity,
                                   State = x.LocationState,
                                   Zip = "'" + x.LocationZip,
                                   CreatedOn = x.CreatedDate
                               });


        grid.DataSource = banks.ToList();
        grid.DataBind();

        string style = @"<style> .textmode { mso-number-format:\@; } </style> ";

        Response.ClearContent();
        Response.AddHeader("content-disposition", "attachment; filename=WelcomeLetterOutput.xls");
        Response.ContentType = "application/excel";
        StringWriter sw = new StringWriter();
        HtmlTextWriter htw = new HtmlTextWriter(sw);
        grid.RenderControl(htw);
        Response.Write(style);
        Response.Write(sw.ToString());
        Response.End();
    }

2 Answers 2

3

I believe the problem is that the link does not have a 'start' or 'end' attribute. So $('a').attr('start', $(this).val()); will not do anything.

<a href="#" id="lnkExport">Export to Spreadsheet</a>

$('#lnkExport').click(function (e){
 e.preventDefault();
 window.location = '/Home/ExportToCsv?start=' + $('#startDate').val() + '&end=' + $('#endDate').val();
});
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you! I used '@Url.Action("ExportToCsv", "Agent")' to get the URL, but this was exactly what i was looking for. Thank you!
1

I also cannot use a form/submit method as that is already being used on this particular form to allow the users to see the data in the date range requested before exporting to the csv.

Well actually you can have 2 submit buttons inside your form and in your POST controller action know which button was clicked in order to act accordingly. Just like that:

<button type="submit" name="btn" value="search">Search</button>
<button type="submit" name="btn" value="export">Export to Spreadsheet</button>

Now your controller action could take a btn argument:

[HttpPost]
public ActionResult SomeAction(MyViewModel model, string btn)
{
    if (btn == "search")
    {
        // The search button was clicked, so do whatever you were doing 
        // in your Search controller action
    }
    else if (btn == "export") 
    {
        // The "Export to Spreadsheet" button was clicked so do whatever you were
        // doing in the controller action bound to your ActionLink previously
    }

    ...
}

As you can see in both cases the form is submitted to the same controller action in which you will obviously get your view model from the form data and in addition to that you will know which button was clicked in order to take appropriate action. So now yo ucan get rid of all the fancy javascript and anchors you might have written. Your application will work even if the user has javascript disabled. It's plain, simple HTML.

NOTE: Bear in mind that what you have shown and called controller method in your question is not something standard in ASP.NET MVC. In ASP.NET MVC those methods have names. Tjeir are called controller actions and must return ActionResults and not void. Also you seem to be using var grid = new System.Web.UI.WebControls.GridView();, seriously, in an ASP.NET MVC application dude?

4 Comments

This was admittedly a hack, what would you suggest?
Using the OpenXML SDK to generate your Excel file: microsoft.com/en-us/download/details.aspx?id=5124
Is this something we'd have to install on the server prior to deployment or would i just need to do that on my local machine once, then add it to the controller?
No, you don't need to install anything. It's an assembly you have to reference in your application.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.