tag hacer formularios form contextual como c# asp.net sql-server database-design aspmenu-control

hacer - menu contextual c#



Diseño de base de datos para el sitio web de la revista con menús horizontales flexibles (4)

Necesito diseñar un sitio web basado en CMS utilizando el formulario web asp.net (c #) y el servidor MS SQL como base de datos para un sitio web de revista que tendrá problemas semanales.

Data de muestra

MagazinePages Table PageID PageName LangID PagePositionNo PageURL PageInheritance //PageID 1 Home 1 10 Default.aspx 0 2 About Us 1 20 Page.aspx 0 3 PageOne 1 10 Page.aspx 2 4 PageTwo 1 20 Page.aspx 2 5 Media 1 30 Page.aspx 0 6 Video 1 10 Videos.aspx 5 8 News 1 40 News.aspx 0 9 Archive 1 50 # 0 10 Publication 1 60 Page.aspx 0 11 SpanishHome 2 10 Default.aspx 0 12 SpanisAboutUs 2 20 Page.aspx 0 ------------------------------------------------------------------------------ Magazine MagazineID MagazineIssueCode LangID MagazineTitle MagazineLiveIssue(CurrentIssue) 1 1 1 Mag Title 0 2 2 1 Mag Title 1 3 1 2 SpanisgMag Title 0 4 2 2 Mag Title 1 ------------------------------------------------------------------------------ News Table NewsID NewsTitle NewsCatID MagazineID Language 1 News one 100 1 1 2 News two 100 1 1 3 news three 200 1 1 4 News four 300 1 1 5 News Five 100 2 1 6 News Six 300 2 1 7 News seven 200 2 2 ------------------------------------------------------------------------------

El problema con el enfoque anterior es que puedo crear submenús solo si todos los registros están en páginas de revistas basadas en el ejemplo anterior. Puedo crear submenús para "Sobre nosotros" y multimedia. ¿Cómo puedo diseñar mi base de datos para poder extraer datos de diferentes tablas? tales como noticias por categoría (Política, Cultura ...) & Issue from Magazine Table (Número 101, Número 102, Número 103 ...)

Estoy planeando utilizar el control del menú ASP para esto, que puede no ser muy flexible, ya que tendré más de 100 ejemplares de cómo o qué menú de columna múltiple puedo usar con asp.net

Mi base de datos puede tener muchos flujos, agradecería ayuda en este sentido para poder utilizar esta base de datos para este sistema CMS. Por favor, siéntase libre de hacer preguntas con respecto a esto.

Agregado : Si necesito extraer todo el nombre del menú de la tabla de MagazinePages , es fácil, pero se me ha pedido que tenga una estructura de menú como se muestra en el ejemplo. Problema con esto es que puedo generar menús para AboutUs y Multimedia desde la Tabla de MagazinePages pero no tengo ninguna página como Política, Económica, ... Número 101, 102, 103 ... en esta Tabla, ya que esa información se almacena en una tabla diferente como News Category de noticias en tabla de noticias y edición en la tabla de Magazine . Prefiero cambiar el diseño de mi mesa y hacer que sea flexible para leer la información del menú de una tabla separada, pero no estoy seguro de cómo

News Table no se muestra en este esquema.

Lo que he hecho es que he creado ps_Pages Table para CMS Pages como, Home, Aboutus, Contact, MediaCentre .....

Guardo páginas relacionadas con la revista (que en realidad son artículos con diferentes categorías o etiquetas como cultura, política, deportes, personas ...) en art_Article table


¿Por qué no tener una sola página con el contenido?

Simplemente llame a Page.aspx?Issue=4&Page=4

Luego, en su código, usted sabe que es el 4º Issue y ellos quieren la página 4, luego puede tener el código en la página.aspx (.vb o .cs) que traduce eso y luego decide el diseño.

Por ejemplo,

Page.aspx?Issue=4&Style=Article&Content=5

Entonces, en el código podría ir, está bien, el problema 4 es obtener las entradas de la base de datos para el Issue 4, está bien, quieren Content ID 5 del Issue 4, y luego ponerlo en el estilo de un artículo.

Esto significa que no tiene que agregar páginas adicionales en el tipo de base de datos, simplemente puede agregar el contenido que desee y el elemento que genera las URL para acceder al contenido solo necesita mostrar todo el contenido.


Creo que necesita volver a evaluar su esquema de base de datos. Por ejemplo, tendría una tabla llamada "ParentMenuItems"

Esta tabla incluye todos los elementos del menú principal (Inicio, Acerca de nosotros, Problemas, etc.) y tiene el texto para los menús secundarios. Entonces necesitas tener una tabla de ChildMenu que tenga relación con tus elementos del menú principal.

ParentMenuItems: ============================================================== ID | LinkText | LangID | Other Properties ============================================================== 1 | Home.aspx | 1 | blah blah blah 2 | AboutUs.aspx | 2 | blah blah blah

Entonces, podría tener otra tabla llamada "ChildMenuItems" como esta:

ChildMenuItems: =============================================================== ID | LinkText | LangID | ParentID | Other Properties... =============================================================== 1 | PageOne.aspx | 1 | 2 | blah blah blah 2 | PageTwo.aspx | 2 | 2 | blah blah blah

El código podría funcionar así:

SELECT * FROM ParentMenuItems - //SQL to get Items

Luego, escriba algún código foreach para enumerar los resultados SQL

foreach(var ParentMenuItem in ParentMenuItems) { //Get ParentMenuItem ID, run SQL select on child menu items, Example: //SELECT * from ChildMenuItems where ParentID = ID.FROM.PARENT.RESULT // Now you have all the child menu items, foreach those and add to repeater control }

Espero que esto ayude. Déjeme saber si usted tiene preguntas.

CONSEJO: Entity Framework hará un trabajo muy ligero de esto.


No estoy seguro de haber entendido lo que necesita, pero supongo que quiere crear un menú para todo el sistema, y ​​no un menú para cada revista, ¿verdad?

Si es así, creo que está buscando el problema equivocado: el problema no es el esquema de la base de datos, sino el concepto de que su menú debe llenarse automáticamente con N tablas diferentes que no tienen un estándar predefinido.

Crearía una tabla de menú, y haría que las páginas de revistas y el menú fueran dos tablas distintas: si está creando un sistema similar a CMS, probablemente tenga una página donde pueda editar categorías, problemas y, por qué no, las entradas de menú, completamente separadas de otras tablas

Además, crearía un sistema de "etiquetas", donde todas mis noticias y problemas podrían ser "etiquetados" en lugar de ponerlos en una categoría exclusiva. Sería posible tener una noticia que habla sobre política y cultura al mismo tiempo. Entonces, en lugar de dirigir al usuario a muchas páginas diferentes.aspx, usaría un content.aspx? Tag = politics. Al crear la etiqueta, tendría la opción de agregar esta etiqueta a la tabla del menú, en "noticias", "problemas", etc. Lo mismo para la categoría y los problemas.

Si no se ajusta a sus necesidades, puede probar esas opciones, pero todas las demás soluciones que no sean una tabla específica para las entradas de menú muestran una "advertencia, problemas futuros detectados" en mi cerebro:

1 - crear una tabla de menú, un procedimiento almacenado que llena esta tabla siguiendo reglas específicas y luego se activa en tablas como "categoría" que truncaría y llamaría al procedimiento almacenado, reescribiendo el menú cada vez que cambia el contenido (me suena como una solución rápida) )

2 - Agregue una "submenu_table", "submenu_field", "submenu_condition", etc. a las páginas de revistas y use sql dinámico para seleccionar datos (algo así como Set @SQL=''Select ''+ submenu_field + '' from ''+ submenu_table + '' where '' + submenu_condition; Exec(@SQL) ) (otra solución rápida, pesada y probablemente una consulta lenta)

(editar :) 3 - también hay un campo de jerarquía en sql 2008 y superior ([http://blogs.msdn.com/b/manisblog/archive/2007/08/17/sql-server-2008-hierarchyid.aspx]) 1


Crea una tabla para el menú

CREATE TABLE [dbo].[tblMenuMaster]( [MenuID] [int] IDENTITY(1,1) NOT NULL, [MenuName] [varchar](100) NULL, [DisplayOrder] [int] NULL, PRIMARY KEY CLUSTERED ( [MenuID] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] GO

Crear otra tabla para el submenú

CREATE TABLE [dbo].[tblSubMenuMaster]( [SubMenuID] [int] IDENTITY(1,1) NOT NULL, [MenuID] [int] NULL, [SubMenuName] [varchar](100) NULL, [MainMenuDisplayOrder] [int] NULL, [DisplayOrder] [int] NULL, [SubMenuUrl] [varchar](500) NULL, [VisibleInMenu] [bit] NULL, PRIMARY KEY CLUSTERED ( [SubMenuID] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] GO

Ahora ve a la página maestra ... El código HTML es:

<div class="menubar"> <%--<ul class="tabs">--%> <asp:Literal ID="ltMenus" runat="server"></asp:Literal> <%--</ul>--%> </div>

Código detrás del código es:

private void GenerateMenus() { clsMenu obj = new clsMenu(); System.Data.DataSet ds = new System.Data.DataSet(); String PageName = ""; PageName = Path.GetFileName(Page.AppRelativeVirtualPath); ds = obj.GetMenusByRole(GetRoleId(), PageName); StringBuilder sb = new StringBuilder("<ul class=''tabs''>"); foreach (System.Data.DataRow row in ds.Tables[0].Rows) { sb.Append(String.Format("<li class=''{0}''><a rel=''{1}'' href=''{1}'' > {2} </a> ", Convert.ToString(row["css"]), ResolveUrl(Convert.ToString(row["PagePath"])), Convert.ToString(row["MenuName"]))); //sb.Append(String.Format("<li ''><a rel=''{0}'' href=''{0}'' > {1} </a> ", ResolveUrl(Convert.ToString(row["PagePath"])), Convert.ToString(row["MenuName"]))); System.Data.DataTable t = CCMMUtility.GetFilterDataforIntColumn("MenuID", Convert.ToString(row["MenuID"]), ds.Tables[1]); if (t.Rows.Count > 0) { sb.Append("<ul>"); for (int i = 0; i < t.Rows.Count; i++) { sb.Append(String.Format("<li><a href=''{0}'' class=''dir'' style=''cursor: pointer;''>{1}</a></li>", ResolveUrl(Convert.ToString(t.Rows[i]["PagePath"])), Convert.ToString(t.Rows[i]["PageAliasName"]))); } sb.Append("</ul>"); } sb.Append("</li>"); } sb.Append("</ul>"); ltMenus.Text = sb.ToString(); }

necesita un proceso almacenado para invocar la dinámica del menú de acuerdo con la Identificación del rol como se muestra a continuación

CREATE PROCEDURE [dbo].[proc_GetMenusByRole] ( @RoleId int, @PageName varchar(100) ) AS SET NOCOUNT ON; SELECT mm.MenuID, mm.MenuName,dbo.Extract_CssNameForMenuByMenuIDAndPageName(mm.MenuID, @PageName) as css ,dbo.proc_Extract_MenuPageByRoleIDAndMenuID(@RoleId, mm.MenuID) as PagePath , mm.DisplayOrder FROM tblMenuMaster mm WHERE mm.MenuID IN (SELECT s.MenuID from tblSiteRolePermissions p INNER JOIN tblSitePages s ON p.fkSitePageId = s.pkSitePageId WHERE (p.fkRoleId = @RoleId and p.ViewOnly=1)) Union All select 0 as menuid ,''Change Password'' as MenuName, case @pagename when ''ChangePassword.aspx'' then ''active'' else '''' end as css,''~/User/ChangePassword.aspx'' as PagePath, 10000 as Displayorder ORDER BY DisplayOrder SELECT s.MenuID, s.pkSitePageId, s.PageAliasName, s.SitePageName,s.pagepath from tblSiteRolePermissions p INNER JOIN tblSitePages s ON p.fkSitePageId = s.pkSitePageId WHERE (p.fkRoleId =@RoleId and p.ViewOnly=1) ORDER BY s.pkSitePageId

// nuevo sp comienza aquí

CREATE function [dbo].[Extract_CssNameForMenuByMenuIDAndPageName](@MenuID int, PageName varchar(100)) returns nvarchar(50) as begin declare @result nvarchar(50) set @result = '''' IF EXISTS (SELECT pkSitePageId FROM tblsitepages WHERE (MenuID = @MenuID) AND (UPPER(SitePageName) = @PageName)) BEGIN SET @result = ''active'' END return @result end

// Otra sp usada es

CREATE function [dbo].[proc_Extract_MenuPageByRoleIDAndMenuID] (@RoleId int, @MenuID int) returns nvarchar(500) as begin declare @result nvarchar(500) SELECT top 1 @result = s.pagepath FROM tblSitePages AS s INNER JOIN tblSiteRolePermissions AS p ON s.pkSitePageId = p.fkSitePageId WHERE (p.fkRoleId = @RoleId) AND (s.MenuID = @MenuID) and p.ViewOnly=1 ORDER BY s.pkSitePageId return @result end

Es solo una manera de hacer esto, puedes modificar esto de acuerdo a tus requerimientos .........

proc_Extract_MenuPageByRoleIDAndMenuID sp se usa para obtener el nombre de la página y su ruta,

Extract_CssNameForMenuByMenuIDAndPageName sp se usa para establecer la clase activa en el primer li significa primer menú. Hop esto te ayudará ... Es el código de trabajo ...