Hur du börjar med ett simpelt cms i asp.net mvc

I asp.net mvc är det lätt att skapa ett simpelt cms liknade system. Det första du ska göra är att skapa ett nytt asp.net mvc projekt. Du behöver inte inkludera något test projekt om du inte vill, för det kommer vi inte använda.

Det första vi gör när vi skapat ett nytt projekt är att lägga till en ny controller (i inlägget kallar vi denna: AdminController.cs)

När vi skapar en controller blir vi tillfrågade: “Add action methos for Create, Update, and Details scenarios”. Vi väljer att ta med detta, så vi klickar i kryssrutan.

 

1

Nu så behöver vi skapa en databas ,det gör vi genom att högerklicka på App_Data mappen i ditt webb projekt och välj Add –> New item, Sql Server database. Som du döper till något vettigt. (döpte min till MvcCms.mdf)

I databasen behöver vi lägga till en tabell med namnet: Page och som innehåller: Id(Int, räknare, nyckel), Title(Nvarchar(100)), Content(Nvarchar(max)).

I våran Models mapp i så skapar vi en ny ADO.NET Entity Data Model vid namn Page. (I codebehind sen blir det Pages, då den lägger på ett S)

I models mappen har jag även lagt till en klass kallad Page

    public class Page
{
public int Id { get; set; }
public string Title { get; set; }
public string Content { get; set; }
}

Nu ska vi göra en lista av alla sidor som finns i våran databas när man går till /Admin. Då ser det ut såhär i våran AdminController:

using MvcCms.Models;
        public ActionResult Index()
{
Entities ent = new Entities();
IEnumerable<Page> pages = (from f in ent.Pages
orderby f.Id descending
select new Page
{
Id = f.Id,
Title = f.Title,
Content = f.Content,
TitleUrl = f.TitleUrl,
});

return View(pages);

}

 

(Entities är namnet på min ado.net data modell). När vi gjort detta högerklickar vi på namnet Index() och väljer “Add View”.

2

View name är Index precis som i våran AdminController, Vi skapar också en “Create a strongly-typed view” med våran Page klass som list, Sen är det dina inställningar till masterpage och vilket ContentPlaceHolder ID.

Våran html upplägg ser nu ut såhär, jag gjorde några ändringar:

    <h2>
Index</h2>
<table>
<tr>
<th>
</th>
<th>
Id
</th>
<th>
Title
</th>
<th>
Content
</th>
<th>
TitleUrl
</th>
</tr>
<% foreach (var item in Model)
{ %>
<tr>
<td>
<%= Html.ActionLink("Edit", "Edit", new { id = item.Id }) %> |
<%--<%= Html.ActionLink("Details", "Details", new { /* id=item.PrimaryKey */ })%>--%>
</td>
<td>
<%= Html.Encode(item.Id) %>
</td>
<td>
<%= Html.ActionLink(item.Title, item.TitleUrl, "Pages") %>
</td>
<td>
<%= Html.Encode(item.Content) %>
</td>
<td>
<%= Html.Encode(item.TitleUrl) %>
</td>
</tr>
<% } %>
</table>
<p>
<%= Html.ActionLink("Create New", "Create") %>
</p>

Alla item i våran lista skrivs ut med Html.Encode() men vi ändrar den till en Html.ActionLink för våran title så det blir en klickbar länk genom att skriva

<%= Html.ActionLink(item.Title, item.TitleUrl, "Pages") %> 

Det mesta säger sig själv i våran actionlink. “Pages” är våran router som vi kommer skriva till i global.asax

I global.asax filen finns det redan ett upplägg för vad som ska vara första sidan.

Vi skapar en ny MapRoute innan “Default” MapRoute som ser ut så här:

            routes.MapRoute("Pages", "page/{TitleUrl}",
new { controller = "Home", action = "Page" },
new { TitleUrl = @"(.*)+" }
);

Vi skapar två stycken objekt, den första där vi bestämmer vilken kontroll och view vi ska använda. Sen skapar vi ett till objekt som vi bara skriver in TitleUrl i. “(.*)+” är som en valing string för regex som kan innehålla allt.

Så våran routing blir “page/{TitleUrl}” ex: localhost/page/om-oss. Det behöver inte vara “page” det kan stå “sidor” också. Men det är bra att inte använda åäö.

Vi kan nu återvända till AdminController där vi skapar en Create view från koden. Notera att det finns två stycken ActionResult Create, där vi ska använda den som inte har [AcceptVerbs(HttpVerbs.Post)]. Den ska vi använda senare.

3

Nu får vi massa html i våran Create.aspx men vi gör några ändringar så det ser ut såhär:

    <h2>Create</h2>

<%= Html.ValidationSummary("Create was unsuccessful. Please correct the errors and try again.") %>

<% using (Html.BeginForm()) {%>

<fieldset>
<legend>Fields</legend>
<p>
<label for="Title">Title:</label>
<%= Html.TextBox("Title") %>
<%= Html.ValidationMessage("Title", "*") %>
</p>
<p>
<label for="Content">Content:</label>
<%= Html.TextArea("Content") %>
<%= Html.ValidationMessage("Content", "*") %>
</p>
<p>
<label for="TitleUrl">TitleUrl:</label>
<%= Html.TextBox("TitleUrl") %> <a href="javascript:void(0)" onclick="string_to_slug()">Gör vänlig url</a>
<%= Html.ValidationMessage("TitleUrl", "*") %>
</p>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>

<% } %>

<div>
<%=Html.ActionLink("Back to List", "Index") %>
</div>

Vi skapar en vanlig a href för att anropa vårat javascript för att konvertera titeln till en vänlig url.

 

<a href="javascript:void(0)" onclick="string_to_slug()">Gör vänlig url</a>

För att skapa string_to_slug() så använder vi denna javascript kod: http://dense13.com/blog/2009/05/03/converting-string-to-slug-javascript/

Som jag har skrivit om lite, så all javascript ser ut såhär på Create.apsx sidan:

    function string_to_slug() {
var str = $('#Title').val();
str = str.replace(/^\s+|\s+$/g, ''); // trim

// remove accents, swap ñ for n, etc
var from = "ÀÁÄÂÈÉËÊÌÍÏÎÒÓÖÔÙÚÜÛàáäâèéëêìíïîòóöôùúüûÑñÇç·/_,:;";
var to = "aaaaeeeeiiiioooouuuuaaaaeeeeiiiioooouuuunncc------";
for (var i = 0, l = from.length; i < l; i++) {
str = str.replace(new RegExp(from[i], "g"), to[i]);
}

str = str.replace(/[^a-zA-Z0-9 -]/g, '') // remove invalid chars
.replace(/\s+/g, '-') // collapse whitespace and replace by -
.toLowerCase();
insert_slug(str);
}

function insert_slug(str) {
$('#TitleUrl').val(str);
}
Notera att vi måste inkludera jquery på någon sida före denna kod, så jag la en länk på Site.master.
Nu kan vi börja skapa våran funktion som ska lägga till datan i databasen. Det är nu vi ska använda den andra ActionResult Create
        [AcceptVerbs(HttpVerbs.Post)]
public ActionResult Create(string Title, string Content, string TitleUrl)
{
try
{
Entities ent = new Entities();

Pages page = new Pages();
page.Content = Content;
page.Title = Title;
page.TitleUrl = TitleUrl;

ent.AddToPages(page);
ent.SaveChanges();

return RedirectToAction("Index");
}
catch
{
return View();
}
}
public ActionResult Create(string Title, string Content, string TitleUrl) 
Var title, content, titleurl har precis samma namn som i våran Create.aspx. Entites är våran data modell och Pages är våran Page tabell. 
Sen när vi har sparat vår data så återvänder vi till admin index så ska vi kunna se våran nya sida högst upp.
4 

Nu så ska det se ut något såhär. Men vad vore ett cms utan ett sätt att kunna redigera sin sida? Så vi skapar en ny view för Edit precis som förut med Create.

I våran Edit.aspx ser det ut såhär:

    <h2>Edit</h2>

<%= Html.ValidationSummary("Edit was unsuccessful. Please correct the errors and try again.") %>

<% using (Html.BeginForm()) {%>

<fieldset>
<legend>Fields</legend>

<p>
<label for="Title">Title:</label>
<%= Html.TextBox("Title", Model.Title) %>
<%= Html.ValidationMessage("Title", "*") %>
</p>
<p>
<label for="Content">Content:</label>
<%= Html.TextArea("Content", Model.Content) %>
<%= Html.ValidationMessage("Content", "*") %>
</p>
<p>
<label for="TitleUrl">TitleUrl:</label>
<%= Html.TextBox("TitleUrl", Model.TitleUrl) %> <a href="javascript:void(0)" onclick="string_to_slug()">Gör vänlig url</a>
<%= Html.ValidationMessage("TitleUrl", "*") %>
</p>
<p>
<input type="submit" value="Save" />
</p>
</fieldset>

<% } %>

<div>
<%=Html.ActionLink("Back to List", "Index") %>
</div>

 

Jag inkluderar samma javascript som jag har Create.aspx också för man kan vilja ändra på sin url också.

Vi behöver hämta ut våra tre fält som vi vill kunna ändra. Title, Content och TitleUrl. Såhär ser koden ut för det:

        public ActionResult Edit(int id)
{
Entities ent = new Entities();
Page page = new Page();

page.Title = ent.Pages.Where(f => f.Id == id).Select(f => f.Title).First();
page.Content = ent.Pages.Where(f => f.Id == id).Select(f => f.Content).First();
page.TitleUrl = ent.Pages.Where(f => f.Id == id).Select(f => f.TitleUrl).First();

return View(page);
}
Precis som vid Create post action så har vi en Edit post action.
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Edit(int id, string Title, string Content, string TitleUrl)
Men nu så har vi också Id med i våran post. Notera att koden här nedan ser lite annorlunda ut än den för Create.
Entities ent = new Entities();

Pages page = (from f in ent.Pages
where f.Id == id
select f).First();

page.Content = Content;
page.Title = Title;
page.TitleUrl = TitleUrl;

ent.SaveChanges();

return RedirectToAction("Index");
Där våran Pages modell plockar ut allt som har det id vi håller på att uppdatera och vi har ingen AddToPages(page) nu eftersom vi inte ska lägga till en ny sida utan uppdatera den.
Men för att kunna visa sidorna med våran välida urler ex: /page/min-sida så ska vi skapa en ny view i våran HomeController som heter Page.
Såhär ser ActionResult Page koden ut:
        public ActionResult Page(string TitleUrl)
{
if (!String.IsNullOrEmpty(TitleUrl))
{
return View();
}
else
{
return RedirectToAction("Index");
}
}

Där vi har ett id för att kunna visa något på sidan, om vi inte har det så skickar vi vidare förefrågan till startisdan.

5

Nu så ska “View content” vara Details för vi vill bara skriva ut datan från databasen. Om du ändrar namnet Page till något annat få du ändra Page i routing(global.asax filen) också.

I våran MainContent så behöver det bara se ut såhär:

    <h2>
<%= Html.Encode(Model.Title) %>
</h2>
<p>
        <%= Html.Encode(Model.Content) %>
</p>

Eftersom vi inte vill visa Id eller TitleUrl och vi vill att Titeln ska vara större än Content.

För att plocka ut Titeln och Content så lägger vi till denna kod innan för if(id != 0)

    Entities ent = new Entities();
Page page = new Page();

int id = Models.Page.GetIdByTitleUrl(TitleUrl);

page.Title = ent.Pages.Where(f => f.Id == id).Select(f => f.Title).First();
page.Content = ent.Pages.Where(f => f.Id == id).Select(f => f.Content).First();

return View(page);
Models.Page.GetIdByTitleUrl(string) är en funktion för att hämta ut id för den titelurl.
        public static int GetIdByTitleUrl(string TitleUrl)
{
Entities ent = new Entities();
return ent.Pages.Where(f => f.TitleUrl == TitleUrl).Select(f => f.Id).First();
}
På det här sättet kan du bygga ett simpelt cms. I detta inlägg har jag skrivit om hur du skapar nya sidor.
Hoppas ni gillar inlägget, det kanske kommer en del två på detta inlägg där jag kommer skriva om hur man väljer vilka sidor som ska vara med i menyn och hur man ändrar startsidan till sin egen sidan man just skapat.
Exempel på detta.
 

1 Comment

Comments have been disabled for this content.