Mohamed Yousri Mohamed Yousri -4 years ago 111
ASP.NET (C#) Question

How to centralize and redirect WebForm MenuItem links for an asp:Menu on the Server Side?

When I press to go to

add_sellinvoice
it redirects me to another page
add_purchase
invoice and i want it run efficiently by redirecting me to wanted pages.

The code behind is:

protected void Page_Load(object sender, EventArgs e)
{
}

protected void Menu1_MenuItemClick(object sender, MenuEventArgs e)
{
if(e.Item.Value=="add_client")
{
Response.Redirect("Add_Client.aspx");
}
else if(e.Item.Value=="delete_client")
{
Response.Redirect("Delete_client.aspx");
}
else if (e.Item.Value == "update_client")
{
Response.Redirect("Update_client.aspx");
}
else if (e.Item.Value == "retrieve_client")
{
Response.Redirect("Retreive_clientbyname.aspx");
}

else if(e.Item.Value=="add_invoice")
{
Response.Redirect("add_purchinvoice.aspx");
}

else if (e.Item.Value == "delete_invoice")
{
Response.Redirect("delete_purchinvoice.aspx");
}

else if (e.Item.Value == "update_invoice")
{
Response.Redirect("update_purchinvoice.aspx");
}

else if (e.Item.Value == "retreive_invoice")
{
Response.Redirect("retireve_purchaseinvoice.aspx");
}
else if (e.Item.Value == "add_invoice")
{
Response.Redirect("Add_sellinvoice.aspx");
}
else if (e.Item.Value == "delete_invoice")
{
Response.Redirect("Delete_sellinvoice.aspx");
}
else if (e.Item.Value == "update_invoice")
{
Response.Redirect("Update_sellinvoice.aspx");
}
else if (e.Item.Value == "retrieve_invoice")
{
Response.Redirect("retrieve_sellinvoice.aspx");
}
else if (e.Item.Value == "add_item")
{
Response.Redirect("Add_items.aspx");
}
else if (e.Item.Value == "delete_item")
{
Response.Redirect("Delete_items.aspx");
}
else if (e.Item.Value == "update_item")
{
Response.Redirect("Update_items.aspx");
}
else if (e.Item.Value == "retrieve_item")
{
Response.Redirect("retrieve_items.aspx");
}
else if (e.Item.Value == "add_product")
{
Response.Redirect("Add_product.aspx");
}
else if (e.Item.Value == "delete_pruduct")
{
Response.Redirect("delete_product.aspx");
}
else if (e.Item.Value == "update_product")
{
Response.Redirect("Update_product.aspx");
}
else if (e.Item.Value == "retrieve_product")
{
Response.Redirect("retrieve_product.aspx");
}
else if (e.Item.Value == "add_amount")
{
Response.Redirect("Add_amount.aspx");
}
else if (e.Item.Value == "delete_amount")
{
Response.Redirect("Delete_amount.aspx");
}
else if (e.Item.Value == "update_amount")
{
Response.Redirect("Update_amount.aspx");
}
else if (e.Item.Value == "retrieve_amount")
{
Response.Redirect("retrieve_amount.aspx");
}
else if (e.Item.Value == "add_supplier")
{
Response.Redirect("Add_Supplier.aspx");
}
else if (e.Item.Value == "delete_supplier")
{
Response.Redirect("Delete_supplier.aspx");
}
else if (e.Item.Value == "update_supplier")
{
Response.Redirect("update_supplier.aspx");
}
else if (e.Item.Value == "retrieve_supplier")
{
Response.Redirect("retrieve_supplier.aspx");
}
else if (e.Item.Value == "add_prices")
{
Response.Redirect("add_costprice.aspx");
}
else if (e.Item.Value == "delete_prices")
{
Response.Redirect("delete_costprice.aspx");
}
else if (e.Item.Value == "update_prices")
{
Response.Redirect("Update_costprice.aspx");
}
}

protected void Home_LinkButton_Click(object sender, EventArgs e)
{
Response.Redirect("Home Page.aspx");
}
}


The .aspx Webform code that presents my menu is:

<table class="menutable">
<tr>
<td class="menutd">
<asp:Menu ID="Menu1" runat="server"
DynamicEnableDefaultPopOutImage="false"
StaticEnableDefaultPopOutImage="false"
Orientation="Horizontal"
StaticMenuItemStyle-CssClass="staticmenustyle"
DynamicMenuItemStyle-CssClass="dynamicmenustyle" OnMenuItemClick="Menu1_MenuItemClick">
<Items>
<asp:MenuItem Text="Client" Value="m1">
<asp:MenuItem Text="Add Client" Value="add_client"></asp:MenuItem>
<asp:MenuItem Text="Delete Client" Value="delete_client"></asp:MenuItem>
<asp:MenuItem Text="Update Client" Value="update_client"></asp:MenuItem>
<asp:MenuItem Text="Retrieve Client" Value="retrieve_client"></asp:MenuItem>
</asp:MenuItem>
<asp:MenuItem Text="Invoices" Value="m2">

<asp:MenuItem Text="sellinvoice" Value="x1">
<asp:MenuItem Text="Add Invoice" Value="add_invoice"></asp:MenuItem>
<asp:MenuItem Text="Delete Invoice" Value="delete_invoice"></asp:MenuItem>
<asp:MenuItem Text="Update Invoice" Value="update_invoice"></asp:MenuItem>
<asp:MenuItem Text="Retrieve Invoice" Value="retrieve_invoice"></asp:MenuItem>
</asp:MenuItem>
<asp:MenuItem Text="purchaseinvoice" Value="x2">
<asp:MenuItem Text="Add Invoice" Value="add_invoice"></asp:MenuItem>
<asp:MenuItem Text="Delete Invoice" Value="delete_invoice"></asp:MenuItem>
<asp:MenuItem Text="Update Invoice" Value="update_invoice"></asp:MenuItem>
<asp:MenuItem Text="Retrieve Invoice" Value="retrieve_invoice">
</asp:MenuItem>
</asp:MenuItem>
</asp:MenuItem>
<asp:MenuItem Text="Items" Value="m3">
<asp:MenuItem Text="Add Item" Value="add_item"></asp:MenuItem>
<asp:MenuItem Text="Delete Item" Value="delete_item"></asp:MenuItem>
<asp:MenuItem Text="Update Item" Value="update_item"></asp:MenuItem>
<asp:MenuItem Text="Retrieve Item" Value="retrieve_item"></asp:MenuItem>
</asp:MenuItem>
<asp:MenuItem Text="Product" Value="m4">
<asp:MenuItem Text="Add Product" Value="add_product"></asp:MenuItem>
<asp:MenuItem Text="Delete Product" Value="delete_product"></asp:MenuItem>
<asp:MenuItem Text="Update Product" Value="update_product"></asp:MenuItem>
<asp:MenuItem Text="Retrieve Product" Value="retrieve_product">
</asp:MenuItem>
</asp:MenuItem>
<asp:MenuItem Text="Amount" Value="m5">
<asp:MenuItem Text="Add Amount" Value="add_amount"></asp:MenuItem>
<asp:MenuItem Text="Delete Amount" Value="delete_amount"></asp:MenuItem>
<asp:MenuItem Text="Update Amount" Value="update_amount"></asp:MenuItem>
<asp:MenuItem Text="Retrieve Amount" Value="retrieve_amount">
</asp:MenuItem>
</asp:MenuItem>

<asp:MenuItem Text="Supplier" Value="m6">
<asp:MenuItem Text="Add Supplier" Value="add_supplier"></asp:MenuItem>
<asp:MenuItem Text="Delete Supplier" Value="delete_supplier"></asp:MenuItem>
<asp:MenuItem Text="Update Supplier" Value="update_supplier"></asp:MenuItem>
<asp:MenuItem Text="Retrieve Supplier" Value="retrieve_supplier">

</asp:MenuItem>
</asp:MenuItem>
<asp:MenuItem Text="Costs" Value="m7">
<asp:MenuItem Text="Add Prices" Value="add_prices"></asp:MenuItem>
<asp:MenuItem Text="Delete Prices" Value="delete_prices"></asp:MenuItem>
<asp:MenuItem Text="Update Prices" Value="update_prices"></asp:MenuItem>
<asp:MenuItem Text="Retrieve Prices" Value="retrieve_prices"></asp:MenuItem>
</asp:MenuItem>
</Items>
</asp:Menu>
</td>
</tr>

Answer Source

The reason why you are seeing this issue is because you have two menu items with the same value add_invoice, and you aren't checking the context of the parent menu item. The big if statement will find the first branch with this value and ignore the second branch.

<asp:MenuItem Text="sellinvoice" Value="x1">
     <asp:MenuItem Text="Add Invoice" Value="add_invoice">

and

<asp:MenuItem Text="purchaseinvoice" Value="x2">
    <asp:MenuItem Text="Add Invoice" Value="add_invoice">

So you could change the values of the two menu items such that they are unique (e.g. sell_add_invoice and purchase_add_invoice).

However, may I ask why you are centralizing the clicks this way? It causes additional work, i.e. browser posts to server, server decodes the route, and then issues a 302 to get the browser to navigate elsewhere. A MenuItem with NavigateUrl simply emits an <a href="..."> link which will take the user straight to the intended page.

In a simple scenario, you can link the menu items (even if they are nested) directly, by applying the NavigateUrl property to each MenuItem:

<asp:Menu ID="Menu1" runat="server"
    DynamicEnableDefaultPopOutImage="false"
    StaticEnableDefaultPopOutImage="false"
    Orientation="Horizontal"
    StaticMenuItemStyle-CssClass="staticmenustyle"
    DynamicMenuItemStyle-CssClass="dynamicmenustyle"> <%--No MenuItemClick--%>

    <Items>
        <asp:MenuItem Text="Client" NavigateUrl="foo.aspx">
            <asp:MenuItem Text="Add Client" NavigateUrl="bar.aspx">
                <asp:MenuItem Text="Delete Client" NavigateUrl="baz.aspx"></asp:MenuItem>
            </asp:MenuItem>
            <asp:MenuItem Text="Delete Client" NavigateUrl="foo2.aspx"></asp:MenuItem>
        </asp:MenuItem>
    </Items>
</asp:Menu>

Edit

If you absolutely must use a centralized, server side link handler, I would suggest that you change your code behind to make use of a Dictionary to do the mapping:

    private static readonly IDictionary<string, string> MenuLinks = 
         new Dictionary<string, string>
    {
        {"add_client", "Add_Client.aspx"},
        {"delete_client", "Delete_client.aspx"},
        {"add_invoice", "add_purchinvoice.aspx"},
        {"add_invoice", "Add_sellinvoice.aspx"}, // *** Error!
        // ...
    };

    protected void Menu1_MenuItemClick(object sender, MenuEventArgs e)
    {
        string redirectLink;
        if (MenuLinks.TryGetValue(e.Item.Value, out redirectLink))
        {
            // Avoid the thread abort exception of a response.redirect by making sure this is the last action in the page lifecycle
            Response.Redirect(redirectLink, false);
        }
        else
        {
            txtErrorMessage.Text = "Please select a Link";
        }
    }   

Not only will it save you lots of messy if / switch statements, but you will also get a hard error when the duplicate key is detected:

An item with the same key has already been added.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download