Kbdavis07
Kbdavis07

Reputation: 1090

How to Create a CMS Application Using Asp.Net MVC C#

I had reviewed lots of questions already posted on StackOverFlow and most of the answers ended up on what CMS platform to use instead of how to actually create one from Scratch.

Searching the Internet and Books also did not result in any useful answers to my questions.

I am fairly new to using Asp.Net MVC and wanted to know how to make a very basic CMS with Asp.Net, MVC, Entity Framework, in C#.

My main issue is creating database driven pages that are not hard coded into the MVC Controller and not physically located as Somepage.cshtml

Would like to know how to do the following:

Incoming URL: MainWebsite.com/DatabaseProvidedPage

Goal is for the controller in Route for pages without a /controller/ in the URL to default as being a Database Driven/Created Webpage.

Would like to actually know how to do this.

Not looking for a platform to use to do this.

I want to learn the basics of creating a CMS using Asp.Net MVC.

Just really want:

How to do this?

URL: MainWebsite/DatabaseProvidedWebpage --> Return to user the HTML stored in database

Thanks,

Upvotes: 3

Views: 9179

Answers (4)

Jan Lenoch
Jan Lenoch

Reputation: 99

In MVC, use the concept of display/editor templates. They allow you to:

  • Have more abstract views. Views then serve rather as more-specific layouts (in conjunction with your more-generic _Layout.cshtml).
  • Store specific pages as objects of various CLR types in your persistent repository (be it EF or anything else)

The objects should be strongly typed and are supposed to be hierarchically composed of/aggregated of other objects representing the internal parts of the page.

Your views may then look like:

@model BikeStore.Models.BodyPartTwoSecondaryParts

<div class="container body-part">
    @Html.DisplayFor(vm => vm.BodyPart)
</div>
<div class="container">
    <div class="inline-block half-width secondary-part">
        @Html.DisplayFor(vm => vm.FirstSecondaryPart)
    </div>
    <div class="inline-block half-width secondary-part">
        @Html.DisplayFor(vm => vm.SecondSecondaryPart)
    </div>
</div>

It is possible because MVC can automatically render a display/editor template once it sees that data of a certain CLR type appears in the view model. The template is basically an ordinary Razor file that has the same name as the CLR type.

The pages may even have several visual representations (templates) defined. It is possible to invoke them in various parts of the app (i.e. in various views) via custom HTML helpers:

For instance, a SearchResults.cshtml view might just call:

@foreach (var item in Model.SearchResults)
{
    @Html.SearchResultFor(vm => item)
}

The HTML helper method would be:

public static MvcHtmlString SearchResultFor<TModel, TValue>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TValue>> expression)
{
    string typeName = expression.ReturnType.Name;

    return htmlHelper.DisplayFor(expression, $"{typeName}Search");
}

Another question is how to store pages of arbitrarily deep structures via Entity Framework. (I ommit the option to store their full HTML as nvarchar data as this is what a CMS should help you to avoid.)

I cannot tell how complex such code would be. You might probably get inspired by a JSON de-serializing logic in our company's SDK. That method builds a strongly typed model that you can then pass into MVC views and rely on display templates.

If you wish to see the above code examples in context, take a look at one of my posts. You can also examine a working example app that's using our headless CMS as its persistent repository.

Upvotes: 0

Kbdavis07
Kbdavis07

Reputation: 1090

Found Solution:

Routing

// Display Database Provided Page MainSite.Com/{PageName}

routes.MapRoute("DatabasePage", 
"{PageName}", 
new { controller = "Home", 
action = "Index", 
PageName = "" 
});

Controller:

public ActionResult Index(String PageName)
        {
            if (PageName == null)
                {
                    List<PageTable> pages = PagesRepository.GetAllPages();
                    return View(pages);
                }

            PageTable FindPageName = PagesRepository.GetPageByURL(PageName);



            if (FindPageName == null)
                {
                    return Content(PageName);
                }


            if (FindPageName != null)
                {
                    return View(FindPageName);
                }

            return View("");

        }

View

@model CMS_Repository.DAL.EF.PageTable

@{
ViewBag.Title = "Details";
}

<h2>Details</h2>

    <div>
    <h4>PageTable</h4>
    <hr />
    <dl class="dl-horizontal">
        <dt>
            @Html.DisplayNameFor(model => model.Title)
            </dt>

        <dd>
            @Html.DisplayFor(model => model.Title)
        </dd>

        <dt>
            @Html.DisplayNameFor(model => model.Content)
        </dt>

        <dd>
            @Html.DisplayFor(model => model.Content)
        </dd>

        <dt>
            @Html.DisplayNameFor(model => model.FriendlyURL)
        </dt>

        <dd>
            @Html.DisplayFor(model => model.FriendlyURL)
        </dd>

        <dt>
            @Html.DisplayNameFor(model => model.ControllerName)
        </dt>


</dl>

Upvotes: 2

Slippery Pete
Slippery Pete

Reputation: 526

I recommend Microsoft's Introduction to MVC 5. You'll create a website based on their starter project, and it should answer most of your questions on how you can create a CMS.

Upvotes: 0

andypopa
andypopa

Reputation: 536

Scaffolding does this automatically for you, only not with Guids. When you scaffold, you get a controller with several actions, one of which is Details. By accessing /Controller/Details/[id] you see details about the specified item. Create a table with a column for your HTML; let's call it HTML. In the Details view, write

@Html.Raw(Model.HTML)

Upvotes: 1

Related Questions