I'm working on a cshtml file where the user can export a List as an .xsl file.
Like all my others views, this cshtml file is surrounded by my _Layout.cshtml which contains a call of the LogOff built-in function directly in the nav-bar of my application, with the following code :
<li>
@using (Html.BeginForm("LogOff", "Account"))
{
@Html.AntiForgeryToken()
<button type="submit"><i class="fa fa-power-off" aria-hidden="true"></i></button>
}
</li>
The AntiForgeryToken is here because the log off function requires it.
To make the file downloadable, I'm using the Response.AddHeader function as following :
public void ExportListFromTsv(List<FICHECONGE> data)
{
Response.ClearContent();
Response.AddHeader("content-disposition", "attachment;filename=FicheConges.xls");
Response.AddHeader("Content-Type", "application/vnd.ms-excel");
Tools.WriteTsv(data, Response.Output);
Response.End();
}
And the Tools.WriteTsv() function is the following :
public static void WriteTsv<T>(IEnumerable<T> data, TextWriter output)
{
PropertyDescriptorCollection props = TypeDescriptor.GetProperties(typeof(T));
foreach (PropertyDescriptor prop in props)
{
output.Write(prop.DisplayName); // header
output.Write("\t");
}
output.WriteLine();
foreach (T item in data)
{
foreach (PropertyDescriptor prop in props)
{
output.Write(prop.Converter.ConvertToString(
prop.GetValue(item)));
output.Write("\t");
}
output.WriteLine();
}
}
The xls file is correctly generated and downloaded properly, but after that my application try to redirect the user on the current page through the controller. My problem is at this moment, I get an error on the loading of the _Layout.cshtml, at the line of the @Html.AntiForgeryToken() :
System.Web.HttpException: 'Server cannot append header after HTTP headers have been sent.'
I'm not able to understand correctly the problem. As far as I understand, the Response.End() function sends my headers, but the @Html.AntiForgeryToken() function try to add headers and can't because they are already sent, is that it ?
So I thought that I just had to remove the Response.End(), because the headers would be sent at the load of my page anyway. At this point, I didn't get any error and my file was downloaded correctly. But it contains all the html code of the page instead of just the data from the List.
How can I make the file downloadable with the AntiForgeryToken() system ?
I can suggest a quick and good option, You skip the validation for this particular action. How to do that is can be checked here. ignore forgery token mvc