Panelen



Forumnavigering
Senast inloggade
RSS
Sponsorer

Forum > ASP.NET 3.x > Språk - C#

Dynamisk meny i Master Page (MVC)

Shadi
Shadi

Gradering

#19431

Hej!

Nu har jag tagit upp .NET pluggandet och det första jag gjort är att skapa ett nytt MVC projekt i Visual Studio 2008. Nu vill jag generera en meny i Master Page från databasen, men vet dock inte hur jag ska göra. Borde inte Site.Master ha någon .cs fil som man kan använda? Alternativt en Controller?

Jag är helt ny när det gäller MVC, så jag uppskattar ifall ni förklarar era svar.

Administratör på AspKoll.se!
ID: #19431 | Skapades: 2010-02-13 15:31:57 | Tråden har 13 svar och har lästs 1057 gånger.

Timmie
Timmie

Gradering

#19443

Jag har lite svårt att förklara detta men jag ska göra mitt bästa..

Eftersom att MasterPage enbart ska vara en teamplate så ska du inte ha sådan logik i din MasterPage. Rent teoretiskt så skulle din MasterPage lika gärna kunna vara en .html fil eftersom att den enbart ska göra det lätt för dig och så du slipper skriva om designen på varje sida. Med andra ord så ska din MasterPage t.ex enbart vara en ram till en tavla. Jag har skrivit om det jag skrev nu 100 gånger för jag har så svårt att förklara hur jag tänker att akkt ska vara med MasterPage men hoppas du förstår. Sen så vet jag inte om jag har tolkat allting rätt men det är så jag tänker iaf.

Hur som helst så skulle jag rekommendera dig att du använder dig utav Html.RenderAction() istället för att lägga logiken i din MasterPage. Nu vet jag inte riktigt vad det är du gör för sida men om vi tar att du ska göra om AspKoll till  .NET MVC som exempel så hade jag tänkt såhär:

Det är helt onödigt att skapa en controller enbart till en meny så det är struket. Eftersom att jag kanske vill att enbart de som är inloggade ska kunna komma till en viss sida i menyn så skulle det bästa vara att ha min meny i min UserController eftersom att det är där jag har hand om det mesta som har med användarna att göra.

public ActionResult Index() {
    return View();
}     

public ActionResult Menu() {
    return View();
}


Det ända jag behöver göra nu är att skapa en Web User Control som heter Menu och ha min meny där i. Sen i min MasterPage så behöver jag enbart köra RenderAction och visa vilket ActionResult jag vill köra:

<% Html.RenderAction<UserController>(c => c.Menu()); %>

ID: #19443 | Skapades: 2010-02-15 22:37:07

Shadi
Shadi

Gradering

#19461

Timmie, du är guld. Jag har letat efter någon som kunde hjälpa mig, googlat efter svar men inte hittat något. Det finns säkert många lösningar, men när man inte vet vilka funktioner eller metoder det finns så blir det lite svårt.

Hur som helst. Jag tycker att din lösning låter väldigt intressant och passar mig väldigt bra. Så nu när vi hur valt har man ska lösa det, så kanske det är dags att gå in på lite detaljnivå, hur man ska utforma koden.

Säg att jag har en UserController där menyn hämtas från databasen. Frågan är hur jag skapar en Web User Control och döper den till "Menu". D.v.s. hur skulle du skapa en sådan? Vi börjar där och tar ett steg i taget. Hoppas att du har tålamod med mig =)

EDIT:

Jag har självklart googlat lite ActionResult och läst lite om det, men jag vill bekräfta med dig nu när vi ändå diskuterar. Andra kanske får användning av detta också.

Om jag förstod det rätt så ska man skapa en vanlig Controller (.cs fil), vi kan kalla den för CustomerController.cs där man har en metod som man kanske kallar "Menu", nåt i stil med

public ActionResult Menu() {
Hämta meny från DB
}

Och sen i MasterPage:

<% Html.RenderAction("Menu", new MittProject.Models.Customer() { Id = 1, Name = "Mikael" }); %>

Stämmer det? Nu gissar jag här bara o tar lite kod jag läst om på nätet. Men jag vet inte riktigt ifall det stämmer och vad som saknas.

Administratör på AspKoll.se!
Redigerades av Shadi den 16 februari 2010. Läs tidigare inlägg.
Redigerades av Shadi den 16 februari 2010. Läs tidigare inlägg.
ID: #19461 | Skapades: 2010-02-16 20:26:15

Timmie
Timmie

Gradering

#19463

Det verkar som om du har förstått hur jag tänker. Nu vet jag inte hur mycket kunskap du har om MVC men jag skriver så som jag hade gjort så kanske vi kan få en disskution om det iaf.

När jag gick över från WebForms till MVC så vart jag helt fast i DDD (domain driven design) tänket och hur smidigt man kunde byta O/R Mapper genom att bara använda sig utav dependency injection och IoC container så det tycker jag att du borde kolla upp även om det inte hör till just det här ä,net.

Nu vet jag inte avd du vill ha i menyn men låt oss säga att du ska göra en meny beroende på de olika kategorierna som du har här på AspKoll. Jag skulle ha skapat ett CategoryRepository som med hjälp av en O/R Mapper hämtade alla kategorier och returerade en lista med de. Sen så skulle jag skapa en CategoryController som hade en metod Menu, modeln som skickas med i Menu skulle då vara resultatet från vårat Repository.
Sen så är det bara att göra menyn med en foreach sats i din Web User Control.

namespace MvcTest.Core.Repository {
    // "Category" är namnet på våra entiteter.
    public virtual ICollection<Category> FindAll() {
        // Här kommer våran databas / O/R Mapper in tillexempel EF, LinqToSQL, SubSonic, NHibernate osv.
    }
}

namespace MvcTest.Web.Controllers {
    public class CategoryController : Controller {
        private readonly CategoryRepository _categoryRepository;
        public CategoryController(CategoryRepository categoryRepository) {
            _categoryRepository = categoryRepository;
        ]

        public ActionResult Menu() {
            reutnr View(_categoryRepository.FindAll());
        }   
}

Enbart pseudokod så inget att gå efter men något likande så hade jag gjort det iaf. Dock så hade jag gjort ett interface till varje repository och använda mig av DI och IoC. Känns som jag gör allt mer komplicera tän vad du kanske hade för syfte med tråden men kan ju alltid hoppas på att detta kan bidra till en disskution.

ID: #19463 | Skapades: 2010-02-17 00:28:04

Shadi
Shadi

Gradering

#19487

Jag är rätt så ny i det hela, så jag förstår nog inte alla begrepp som du nämner. Men jag håller på och googlar allt för att få mig en uppfattning om vad det egentligen är jag ska skapa. T.ex. så försöker jag förstå mig på hur en Repository kan se ut. Jag jobbar mot en MySql databas, så här gäller det även att välja "rätt sätt" att koppla sig mot databasen. Jag håller på att läsa lite om Entities just nu.

Det jag har gjort är att jag skapat en Model (DataModel.edmx i mappen Models) där jag har mina databastabeller. Nästa steg är att lyckas skapa en databaskoppling. Jag antar att det är i Repository som jag behöver upprätta en databas koppling, eller har jag fel? Låt oss säga att projektet heter "AspKoll" så den första koden jag skriver är följande:

private AspKollEntities _entities = new AspKollEntities();

Den koden har jag just nu i UserController.cs (i mappen Controllers). Så långt har jag kommit, så du förstår att jag är i början av utvecklingen. Hur kan koden se ut för att hämta allt från MySql databasen i detta fall? Ska den ligga i en Controller som jag börjat att göra?

Administratör på AspKoll.se!
Redigerades av Shadi den 20 februari 2010. Läs tidigare inlägg.
ID: #19487 | Skapades: 2010-02-20 13:52:42

Timmie
Timmie

Gradering

#19490

Jag är också ganska ny på det här men så som jag har fattat det som så ska du inte ha någon databas logik i din controller utan i din Model. Jag rekomenderar starkt att du använder dig utav en O/R Mapper så som Entity Framework, SubSonic, NHibernate då det underlättar groft mycket. Själv använder jag mig utav SubSonic. Låt oss säga att du använder dig utav SubSonic så använder du dig utav SubSOnics metoder för att göra dina databas anropp i ditt repository. SubSonic mappar din data till dina entiteter automatiskt så du slipper göra det själv. Sen i din controller så kör du bara den metoden som du har skapat i ditt repository och skickar värdena till din vy (så som jag visade i koden i mitt förra inlägg).

Om du inte skulle använda dig utav en O/R mapper så skulle du först och främst behöva skriva alla SQL sattser själv men även mappa din data till dina entiter. Kör du med en O/R mapper så löser den det åt dig och du slipper en massa extra jobb.

ID: #19490 | Skapades: 2010-02-21 15:53:11

Shadi
Shadi

Gradering

#19491

Jag har nu installerat SubSonic och ska testa för första gången. Min namespace kallas för AspKoll.Data, så jag börjar så här med min kod:

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Security.Principal;
using System.Web;
using System.Web.Mvc;
using System.Web.Security;
using System.Web.UI;
using AspKoll.Data;

namespace AspKoll.Models
{
    public partial class UserModel : System.Web.UI.Page
    {
        
    }
}

Denna kod är i filen UserModel.cs som ligger i mappen Models. Har jag gjort rätt än så länge? Min tabell heter _menu, så frågan är om jag ska skapa en private sub och lägga in:

_menu Menu = new _menu();

Är jag på rätt väg? Vad är nästa steg?

Administratör på AspKoll.se!
ID: #19491 | Skapades: 2010-02-21 17:05:04

Timmie
Timmie

Gradering

#19492

Varför har du med System.Web.UI.Page?

Använder du dig utav ActiveRecord eller SimpleRepository?

Det ser bra ut men jag skulle hellre se att du körde Menu menu = new Menu(); då class namn ska börja med versal om man ska följa microsoft standraden.

ID: #19492 | Skapades: 2010-02-21 18:07:48

Shadi
Shadi

Gradering

#19493

Jag har faktiskt inget bra svar till varför, jag antog att det kanske skulle behövas. Det verkar fungera utan också.

Jag använder mig av ActiveRecord. Men nu undrar jag hur jag ska göra, för om databastabellen heter _menu så kan jag väl inte döpa om den till Menu? Då måste den väl vara _menu Menu = new _menu(); ? Jag kanske ska inte ens ha den koden ens?

Administratör på AspKoll.se!
ID: #19493 | Skapades: 2010-02-21 18:14:25

Timmie
Timmie

Gradering

#19494

Ja om databastabellen heter _menu så kommer den heta det. Dock så kan du ju ändra så att den heter Menu fast databastabellen heter _menu. Kolla i din settings.ttinclude så ser du där i CleanUp att du kan ändra den genererade klassens namn.

ID: #19494 | Skapades: 2010-02-21 22:45:01

Shadi
Shadi

Gradering

#19495

Men säg att jag har fixat det, hur går man till väga för att skriva ut allt? Behöver jag inkludera flera namespaces? Hur skulle koden se ut för att skriva ut menyn i en UL-list. Säg att tabellen ser ut så här:

id - int
title - varchar
order - int

Hur får jag ut värdena?

Administratör på AspKoll.se!
ID: #19495 | Skapades: 2010-02-21 23:05:06

Timmie
Timmie

Gradering

#19496

Rent teoretiskt så är det bara att göra såhär:

public class HomeController : Controller {
  public ActionResult Menu() {
    return View(Menu.All());       
  }
}


Högerklicka på ActionResult och ta "Add View". Sedan så partial, strongly och väljer AspKoll.Data.Menu eller vad den heter, välj även List. Sen så är det bara att göra om koden som kom till en ul.

ID: #19496 | Skapades: 2010-02-22 00:01:06

Shadi
Shadi

Gradering

#19502

Nu kanske jag låter helt dum här, men den koden jag visade innan var i Models, den koden du skrev ligger i Controllers. Är det inte så att jag kopplar till databasen i Models? Hur kommer de båda filerna "HomeController" och "UserModel" att samarbeta?

Jag tror att det är något stort som jag har missat här :)

EDIT:

Holy crap it worked...kinda :) Jag använde mig inte av UserModel på något sätt, det enda jag gjorde är det du skrev i ditt senaste inlägg, att i HomeController skapa en ActionResult som hämtar allt från "menu" och skapade en View.

Problemet nu är att jag måste navigera till ~/Home/Menu för att jag ska se resultatet. Det jag vill göra är att jag vill inkludera allt i min masterpage. Jag försökte att skriva

Html.RenderAction(...

Men jag får inte fram RenderAction i förslagsmenyn, bara RenderPartial.

Administratör på AspKoll.se!
Redigerades av Shadi den 22 februari 2010. Läs tidigare inlägg.
ID: #19502 | Skapades: 2010-02-22 20:45:24

Timmie
Timmie

Gradering

#19503

Ja du ska ha din egentligen ha det i din Model, därför jag skrev rent teoretiskt. :)

Sitter just nu på jobbet så kan inte kolla själv men vilken version av MVC kör du? Kan vara så att RenderAction inte kom förrens i 2:an. Då jag är väldigt dålig på att förklara hur man gör så kanske jag kan slänga ihop ett skript som så önskas? Om jag kunde förklara så skulle jag ha gjort en artikel men jag är sämst på att förklara det jag gör. Jag gör det bara för att jag vet att man ska / kan göra så.

ID: #19503 | Skapades: 2010-02-22 21:35:56
© Copyright 2007-2009 Shadi Domat | Version 3.0 | Sidkarta | Policy