Ariel Seah
Ariel Seah

Reputation: 65

ASHX handler throwing value cannot be null error

I wanted to display a list of files in a specific folder as hyperlinks, and when the user click on the link, it will open the respective file to prompt the user to download or view but there is a constant error saying:

{"Value cannot be null.\r\nParameter name: filename"} at the line context.Response.WriteFile(context.Request.QueryString["files"]);

I've tried lots of ways but to no avail.

ASHX file:

protected void Page_Load(object sender, EventArgs e)
{
    if (!Page.IsPostBack)
    {
        var directory = new DirectoryInfo("C:\\temp\\Safety&Security");
        var files = (from f in directory.GetFiles()
                     orderby f.LastWriteTime descending
                     select f).First();
        //string[] files = Directory.GetFiles(@"C:\temp\Safety&Security");
        //files = files.Substring(files.LastIndexOf(("\\")) + 1);
        rpt.DataSource = files;
        rpt.DataBind();
    }

    if (!Page.IsPostBack)
    {
        string[] files = Directory.GetFiles(@"C:\temp\marketing");
        Repeater1.DataSource = files;
        Repeater1.DataBind();
    }

    if (!Page.IsPostBack)
    {
        string[] files = Directory.GetFiles(@"C:\temp\IT");
        Repeater2.DataSource = files;
        Repeater2.DataBind();
    }
}

protected void rpt_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
    if (e.Item.ItemType == ListItemType.AlternatingItem || e.Item.ItemType == ListItemType.Item)
    {
        string file = e.Item.DataItem as string;
        HyperLink hyp = e.Item.FindControl("hyp") as HyperLink;
        hyp.Text = file;
        hyp.NavigateUrl = string.Format("~/Handlers/FileHandler.ashx?file={0}", file);
        FileInfo f = new FileInfo(file);
        FileStream s = f.Open(FileMode.OpenOrCreate, FileAccess.Read);
    }
}

public void ProcessRequest(HttpContext context)
{
    //Track your id
    //string id = context.Request.QueryString["id"];
    context.Response.Clear();
    context.Response.Buffer = true;
    context.Response.ContentType = "application/octet-stream";
    context.Response.AddHeader("Content-Disposition", "attachment; filename=" + context.Request.QueryString["files"]);
    context.Response.WriteFile(context.Request.QueryString["files"]);
    context.Response.End();
}

public bool IsReusable
{
    get { return false; }
}

This is the index page codes:

<li class='has-sub'><a href='#'><span>Safety, QA & Security</span></a>
    <ul>
        <asp:Repeater ID="rpt" runat="server" OnItemDataBound="rpt_ItemDataBound">
            <ItemTemplate>
                <asp:HyperLink ID="hyp" runat="server" target="_blank" a href="/Handlers/FileHandler.ashx?id=7"/> 
                <%-- another method of listing all files in specific folder --%>            
                <%--<% foreach(var file in Directory.GetFiles("C:\\temp\\Safety&Security", "*.*", SearchOption.AllDirectories)) { %>
                <li><%= file.Substring(file.LastIndexOf(("\\"))+1) %></li>      
                 <% } %> --%>
            </ItemTemplate>
        </asp:Repeater>
    </ul>
</li>

Upvotes: 1

Views: 619

Answers (1)

garethb
garethb

Reputation: 4041

You've made a silly mistake!

hyp.NavigateUrl = string.Format("~/Handlers/FileHandler.ashx?file={0}", file);

context.Response.WriteFile(context.Request.QueryString["files"]);

You're setting the querystring as 'file' but reading the querystring as 'files' which doesn't exist. Try

context.Response.WriteFile(context.Request.QueryString["file"]);

EDIT:

Try this code. First add a file in your c:\temp called test.txt and put some text in there. In your aspx:

<li class='has-sub'><a href='/Handlers/FileHandler.ashx?file=c:\temp\test.txt'><span>Safety, QA & Security</span></a></li>

In your handler:

public void ProcessRequest(HttpContext context)
{
    //Track your id
    //string id = context.Request.QueryString["id"];
    context.Response.Clear();
    context.Response.Buffer = true;
    context.Response.ContentType = "application/octet-stream";
    context.Response.AddHeader("Content-Disposition", "attachment; filename=" + context.Request.QueryString["file"]);
    context.Response.WriteFile(context.Request.QueryString["file"]);
    context.Response.End();
}

public bool IsReusable
{
    get { return false; }
}

Set a breakpoint in your handler and make sure your handler gets hit when you debug. This code won't work as you need it to because of the other problem I mentioned in the comments about your data binding not working but you should at least get the querystring in your handler and the text file will download.

Upvotes: 2

Related Questions