skip to Main Content

Trying to order a list of files that are sitting in a folder. I am able to display the files just fine and the links work but cannot order them by the file name while removing the last 4 characters (.xlsx). It’s ordered by the first 2 digits and I need to remove the last 4 characters ".xls" from the end of the file name. The list of files are:
01-07-2022.xlsx
12-03-2021.xlsx
11-05-2021.xlsx
etc.

I need them in that order and removing the .xlsx as it shows that name on the page. Right now it displays incorrectly below as:

12-04-2020.xlsx
12-03-2021.xlsx
11-07-2020.xlsx
11-05-2021.xlsx
10-01-2020.xlsx

just reading the first 2 digits for 12, 11, 10…etc. and then it shows a mix of the years.

My code to remove the characters and display in order.
Design View:


                                        <div id="pccommlist" runat="server" visible="true">
                                            <asp:DataList ID="PCDataList" runat="server" RepeatColumns="1" BorderWidth="0" CellPadding="3" ForeColor="#2ba6cb"
                                                Width="100%">
                                                <FooterStyle BackColor="#ffffff" />
                                                <ItemTemplate>
                                                    <asp:ImageButton Width="16px" ID="excelimage" runat="server" BorderStyle="None" ImageUrl='../imagessecure/icons/lists/excel.png' Height="16px" />
                                                    &nbsp;Precinct as of <asp:Label ID="lblDate" runat="server" />
                                            <asp:HyperLink runat="server" NavigateUrl='<%#"pcredirect.aspx?name=" + DataBinder.Eval(Container.DataItem, "Name").ToString()%>' ID="pcLink" Target="_blank"
                                                Text='<%# DataBinder.Eval(Container.DataItem, "Name").ToString() %>'>   
                                            </asp:HyperLink>
                                                </ItemTemplate>
                                                <FooterStyle BackColor="White" ForeColor="#2ba6cb" />
                                                <ItemStyle BorderColor="White" BorderStyle="None" BorderWidth="0" HorizontalAlign="Center"
                                                    VerticalAlign="Bottom" BackColor="White" ForeColor="#2ba6cb" />
                                            </asp:DataList>
                                        </div>

Code Behind. Was trying to order it by creation time which was ideal and then tried full name as you see the commented out code above the FullName line.

    private void GetXLS()
    {

        DirectoryInfo dir = new DirectoryInfo(MapPath("~/pcselect2022/"));
        //FileInfo[] fileArray = dir.GetFiles("*.xlsx").OrderByDescending(p => p.CreationTimeUtc).ToArray(); //pull ONLY the xlsx files
        FileInfo[] fileArray = dir.GetFiles("*.xlsx").OrderByDescending(p => p.FullName).ToArray(); //pull ONLY the xlsx files
        char[] trimChars = { '.', 'x', 'l', 's' };
        string fileName = fileArray.ToString().TrimEnd(trimChars);

        //decide if we need to make controls visible
        pccommlist.Visible = fileArray.Length > 0;
        PCDataList.DataSource = fileArray;
        PCDataList.DataBind();
    }

2

Answers


  1. It looks like you want to sort by date (chronologically), but the values you are sorting are strings. Further, the strings are month/day/year, so they cannot be sorted alphabetically and appear in the order you are expecting. If they were iso format (eg yyyy-mm-dd) then they could be sorted alphabetically and also be chronological. (see: Sort array by ISO 8601 date).

    So your options:

    1. Rename your files and require that they be named in ISO 8601

    2. Create a class / model that can hold the filename and a datetime (DocumentDate or something). When you build up the list, parse the string filename value and create a date time out of it, and use the DocumentDate to do the sorting, and Filename for display

    Login or Signup to reply.
  2. I would probably use a grid, say with markup like this:

         <div style="width:20%;padding:25px">
            <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" CssClass="table" >
                <Columns>
                    <asp:BoundField DataField="FileName" HeaderText="FileName"        />
                    <asp:TemplateField HeaderText="View" ItemStyle-HorizontalAlign="Center">
                        <ItemTemplate>
                            <asp:ImageButton ID="cmdExcel" runat="server" Height="48px" Width="48px" 
                                ImageUrl="~/Content/excel.png"
                                PostBackUrl ='<%# Eval("URL") %>'  />
                        </ItemTemplate>
                    </asp:TemplateField>
                </Columns>
            </asp:GridView>
        </div>
    

    And then your code to load could be this:

       protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
                LoadGrid();
        }
    
        void LoadGrid()
        {
             
            DataTable dt = new DataTable();
            dt.Columns.Add("FileDate", typeof(DateTime));
            dt.Columns.Add("FileName", typeof(string));
            dt.Columns.Add("URL", typeof(string));
    
            DirectoryInfo MyDir = new DirectoryInfo(MapPath("~/pcselect2022/"));
            FileInfo[] MyFiles = MyDir.GetFiles("*.xlsx");
            foreach (FileInfo OneFile in MyFiles)
            {
                DataRow OneRow = dt.NewRow();
                OneRow["FileName"] = Path.GetFileNameWithoutExtension(OneFile.Name);
                OneRow["URL"] = @"pcredirect.aspx?name=" + OneFile.Name;
                OneRow["FileDate"] = DateTime.ParseExact(OneRow["FileName"].ToString(),
                                     "MM-dd-yyyy", CultureInfo.InvariantCulture);
                dt.Rows.Add(OneRow);
            }
    
            // order table by FileName (DATE type)
            dt.DefaultView.Sort = "FileDate";
    
            GridView1.DataSource = dt;
            GridView1.DataBind();
        }
    

    And now you get this:

    enter image description here

    So, you can put the file create date, or file name without extension into the above list. And we can convert the file format to a date, and then it will sort correctly as per above code. So, create a table, and then you can sort by default view, or whatever.

    Also, note how we pulled out the URL expression – might as well add the extra junk to that URL in place of a more complex expression in the markup.

    Edit: – date format was wrong

    Note the date format as original posted was wrong, I used "mm", and you need to use "MM". Hence this:

     OneRow["FileDate"] = DateTime.ParseExact(OneRow["FileName"].ToString(),
                         "MM-dd-yyyy", CultureInfo.InvariantCulture);
    

    ("mm" needs to be MM).

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search