Sorted By: Month (9) and Year (2011)

How to Detect Errors of Our ASP.NET MVC Views on Compile Time - Blow up In My Face Theory

We will see How to detect errors of our ASP.NET MVC views on compile time inside Visual Studio.
2011-09-29 05:04
Tugberk Ugurlu


head-in-a-cake

Yesterday, I saw a question on stackoverflow.com asking why Visual Studio doesn’t know that the app is going to fail when there is an error on your code inside your views. This is a good question and it brings up an philosophical question :

Do we trust compile time check?

In my opinion, no. If this was the case, there would be no point for TDD, even Unit Testing.

Compile time check is no more useful than your Microsoft Word’s spell checker. It helps a lot but it is basically a spell checker.

 

In this blog post, I am trying a new way of blogging which I just learnt from Phil Haack Smile Put unrelated photo to your blog post. This approach is among Top 10 Blogging Clichés of 2010. It was a not-to-do but here I am doing it.

The basic problem here is that Visual Studio is not even useful as a spell checker. How so? Let me show you an example.

works-on-my-machine-seal-of-approval

NOTE

Couple of days ago, I saw something cool from one of Scott Hanselman‘s blog posts : The "Works on My Machine" Certification Program. This blog post fits very well in this program so here Works on My Machine Seal of Approval.

Silently Blow up

I have simple ASP.NET MVC 4 internet application which we get out of the box (Things that I will show can be applied with ASP.NET MVC 3 as well). Then I will put a bug inside the index view of my home controller :

@{
    var poo = "bar"
    }

<h3>We suggest the following:</h3>

As you can see it is not a valid code. So it should fail on both compile time and runtime, right? Let’s build the project first :

image

Successful! Let’s run it :

image

Boom! Now you have a new, polished ScottGu’s YSOD (Yellow Screen of Death). So, the question here is why it wasn’t caught by VS.

By default, on ASP.NET MVC projects, your views aren’t compiled on build process of your application. VS treats your views just like it treats CSS files. This doesn’t mean that VS isn’t doing its job, it certainly does. Here is a proof of it :

I went into my index.cshtml file and and press CTRL+W, E to bring up the Error List window. Here is the result :

image

Everything is there. But how many of us really check this window on regular basis unless you work on a team project and your team has a habit of putting #warning blocks inside your C# codes. Probably a few of us.

What we can do here is a fairly simple action to get this blow up on compile time.

Blow Up In My Face so I can See you

Right click on your project inside solution explorer and click Unload Project section as follows :

image

After that your project will be unloaded.

Then, right click it again and it will bring up much shorter. From that list, click on Edit {yourProjectName}.csproj section (If your project is a VB project, then .csproj should be .vbproj) as follows :

image

As you will see, there is so much going on there. We won’t dive into detail there. What we will simply do is to toggle MvcBuildViews node from false to true :

image

Save the file and close it. Then, right click on your project inside solution explorer again. This time click Reload Project section :

image

Finally, press CTRL+W, O to bring up the Output window, build your project and watch it fail :

image

Now, when we correct the bug, we will see that we will have a successful build. Note that this won’t compile your views into a .dll file, this action will only check them for any compile time errors.

Hope that this helps.

Remove Trailing Slash From the URLs of Your ASP.NET Web Site With IIS 7 URL Rewrite Module

One of the aspect of SEO (Search Engine Optimization) is canonicalization. In this blog post, we will see how easy to work with IIS Rewrite Module in order to remove evil trailing slash from our URLs
2011-09-11 07:08
Tugberk Ugurlu


redirect-me-baby

One of the aspect of SEO (Search Engine Optimization) is canonicalization. Canonicalization is the process of picking the best URL when there are several choices according to Matt Cutts, the head of Google’s Webspam team.

Here is how Matt Cutts explains what canonical URL is :

“Sorry that it’s a strange word; that’s what we call it around Google. Canonicalization is the process of picking the best URL when there are several choices, and it usually refers to home pages. For example, most people would consider these the same URLs:

  • www.example.com
  • example.com/
  • www.example.com/index.html
  • example.com/home.asp

But technically all of these URLs are different. A web server could return completely different content for all the URLs above.”

If you have multiple ways of reaching your web page (as above), then you need to sit down because it is time to make some decisions my friends.

Trailing Slash is Evil

Let’s assume that we have created a web application, an ASP.NET MVC app because we are so cool. We have our pretty URLs as well.

Let’s go to a page on our web site :

http://localhost:55050/Home/About

image

And another page :

http://localhost:55050/Home/About/

image

We have got the same page content. As we have mentioned before, these two will be treated as two different web page and it will confuse the search engine a bit (even if they are so smart today).

The solution is pretty simple : when a page is requested with trailing slash, then make a 301 (permanent) redirect to the non-trailing-slash version.

IIS URL Rewrite Module

There are several ways of doing that with ASP.NET architecture :

  • You could write your own HttpModule to handle this.
  • You could do a poor man’s redirection on your controller (on your page load if the application is a web forms application).
  • You could use IIS URL Rewrite Module to easily handle this.
  • And so on…

In this quick blog post, I will show how we can implement this feature for our whole web site with IIS Rewrite Module.

URL Rewrite Module is an awesome extension to IIS. Installing it to your web server is also pretty easy if you haven’t got it yet. Just run the Web Platform Installer on your server, and make a search for “url rewrite”. Then the filtered result will appear and you will see if it is installed or not :

image

After you have it, you will see the management section inside your IIS Manager under IIS section :

image

Cut the crap and show me the code

Now, we are all set up and ready to implement this feature. As it is usual nearly for all Microsoft products, there are thousands (ok, not thousand but still) of way to approach this feature but the easiest way of implementing it is to write the logic inside your web.config file.

As you already know, there is a node called system.webServer under the root configuration node. IIS Rewrite Module reserves a node under system.webServer section and allow us to configure the settings there pretty easily. What we will do is to only write the following code under system.webServer node :

<rewrite>
  <rules>
  
    <!--To always remove trailing slash from the URL-->
    <rule name="Remove trailing slash" stopProcessing="true">
      <match url="(.*)/$" />
      <conditions>
        <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
        <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
      </conditions>
      <action type="Redirect" redirectType="Permanent" url="{R:1}" />
    </rule>
    
  </rules>
</rewrite>

What this code does is to tell the module to remove the trailing slash from the url if there is one and make 301 permanent redirect to the new URL.

Don’t allow the code to freak you out. It might look complicated but there are good recourses out there to make you feel better. Here is one of them :

Using the URL Rewrite Module by Ruslan Yakushev

When you run your site after this implementation and navigate to /Home/About/, watch what is going to happen :

image

image

Isn’t that awesome? A little effort and perfectly clean way of implementing the 1 of a thousand parts of canonicalization.

Some Gotchas

  • In your development environment, if you run your web site under Visual Studio Development Sever, you won’t be able to see this feature working. You need to configure your application to run under at least IIS Express to see this feature working.
  • When you deploy your web site and see this feature not working on your server, it is highly possible that you misconfigured something on your server. One of the misconfiguration you might have done could be setting the overrideModeDefault attribute to Deny for rules under <sectionGroup name="rewrite"> inside your applicationHost.config file.
  • If you are on a shared hosting environment and you see this feature not working, then ask your provider if they have given you the permission of configuring this part.

Working With JQuery Ajax API on ASP.NET MVC 3.0 - Power of JSON, JQuery and ASP.NET MVC Partial Views

In this post, we'll see how easy to work with JQuery AJAX API on ASP.NET MVC and how we make use of Partial Views to transfer chunk of html from server to client with a toggle button example.
2011-09-09 17:23
Tugberk Ugurlu


JQuery-logo

So, here it is. Nearly every blog I occasionally read has one JQuery related post which has JQuery ‘write less, do more’ logo on it. Now, I have it either Smile This is entirely not the intention of this blog post. What the real intention of this blog post is to lay down some useful stuff done with JQuery Ajax API on ASP.NET MVC 3.0 framework.

I am no expert on neither JQuery nor JavaScript but I am working on it and I hit the resources so hard nowadays. I am no expert on ASP.NET MVC either but I am sure I am pretty damn good at it. It is my favorite platform since v1.0.

ASP.NET MVC embraces the web (html, http, plain JavaScript) and enables you to move which direction you want on your layout. I mean you can real have your way. So, it is so important here to be able to use JavaScript (for most, it is not JavaScript anymore. It is JQuery. Don’t be surprised if you see Content-Type: text/jquery response header) as Ninja in order to get the most out of ASP.NET MVC’s V part (V as in View).

Easiest way to get JQuery package into your ASP.NET MVC 3.0 project is to do exactly nothing. No kidding, it is already there if you install the ASP.NET MVC 3 Tools Update

If you would like to get the latest version of it (which the below samples has been written on), simply type Update-Package JQuery inside PMC (Package Manager Console) and hit enter and you will be done !

Let’s get it started then.

Overview of the Process

Setting expectations correctly is the real deal. We need to set them correctly so that we will be as satisfied as we planned. In this quick blog post, I will walk you through a scenario: a basic to-do list application. We will:

  • Make AJAX calls to our server,
  • Display loading messages while processing,
  • Make use of partial views when we need to update our web page seamlessly.

File New > Project > ASP.NET MVC 3 Web Application > Internet Application > Razor View Engine > No thanks, I don’t want the test project > OK

So the mini title above actual explains what we need to do first, briefly Smile What I would like to do first is to set up my model, ORM (I will use Entity Framework for that) and database.

The main concern of this blog post is AJAX API usage on ASP.NET MVC so I am not go through all the steps of creation our model, database and all that stuff. I will put the sample code at the bottom of this blog post so feel free to dig into that

Then I will make sure to update my JQuery Nuget package to the latest one. I will tweak the default application a little bit as well.

Go get him tiger

Now we are all set up and ready to rock. Let’s begin.

imageOur database here is so simple as you can see on the left hand side. I have created the database with SQL Server Compact edition because database is not the point we are emphasizing on this post.

Our application will only consist one page and we will do all the work there.

First, I will create the JQuery structure. As I mentioned, we will display user friendly loading message to the end user. In order to do that, we will use JQuery.UI dialog api. We will have it inside our _layout.cshtml page (the reason why we do that is to be able to use it everywhere without writing it again. This app might contains only one page but think about multiple page apps for this purpose).

The code for that is really simple actually. We will only have a section defined as html code inside the DOM and we will turn that into a JQuery.UI dialog for loading messages.

Below is the html code for our loading box :

        <div id="ajax-progress-dialog">
            <div style="margin:10px 0 0 0;text-align:center;">
                <img src="@Url.Content("~/Content/img/facebook.gif")" alt="Loading..." />
            </div>
        </div>

Very simple html (please forgive me for putting the style code inline Smile). The below JQuery code will handle this html code :

        (function () {
            $(function () {
                //Global ajax progress dialog box
                //Simply run $("#ajax-progress-dialog").dialog("open"); script before the ajax post and
                //$("#ajax-progress-dialog").dialog("close"); on the ajax post complate
                $("#ajax-progress-dialog").dialog({
                    autoOpen: false,
                    draggable: false,
                    modal: true,
                    height: 80,
                    resizable: false,
                    title: "Processing, please wait...",
                    closeOnEscape: false,
                    open: function () { $(".ui-dialog-titlebar-close").hide(); } // Hide close button
                });
            });
        })();

With this approach, we set up an environment for ourselves to open this dialog when we start the AJAX call and close it when the action is completed.

Some of you guys probably think that .ajaxStart() and .ajaxComplate() would be a better fit here but I don’t. They will hook up the functions for all the AJAX calls but we might need separate loading messages. With the above approach we will call the global loading message only when we need it.

imageNow we can move up. I have added some items to the list manually and list then on the page and we have the result as the picture on the left side.

It is quite simple yet but don’t worry, it will get messy in a moment. First thing that we will do here is to add a functionality to enable toggling IsDone property of the items. When we click the anchor, the To-Do item will be marked as completed if it is not and vice versa.

Let’s look at the view code here before doing that because there is some fundamental structure for our main purpose here :

@model IEnumerable<JQueryAJAXToDoListMVCApp.Models.ToDoTB>

@{
    ViewBag.Title = "Tugberk's To-Do List";
}

@section Head { 
    <script>
        (function () {
            $(function () {
                //JQuery code will be put here
            });
        })();
    </script>
}

<h2>Tugberk's To-Do List</h2>

<div id="to-do-db-list-container">
    @Html.Partial("_ToDoDBListPartial")
</div>

As you can see have rendered a partial view here. The complete partial view code is as follows :

@model IEnumerable<JQueryAJAXToDoListMVCApp.Models.ToDoTB>

<table style="width:100%;">

    <tr>
        <th>Item</th>
        <th>Creation Date</th>
        <th>IsDone</th>
    </tr>

@foreach (var item in Model) {
    <tr>
        <td>@item.Item</td>
        <td>@item.CreationDate</td>
        <td>@item.IsDone</td>
    </tr>   
}

</table>

So why we did that is a good question in this case. When we need to make a change to our list view through an AJAX call, we will render this partial view on our controller method and send it back to the client as JSON result. This partial view will be our template here. When we make a change to this partial view, this change will be made all of the places that use this partial view which is kind of nice.

Also, this action will show us one of the main fundamentals of ASP.NET MVC which is separation of concerns. View doesn’t care how the model arrives to it. It will just displays it. The same is applicable for controller as well. It does not care about how the view will display the model. It will just pass it.

Let’s put the above paragraph in action. First, we need to make a little change to our partial view for toggle function :

@foreach (var item in Model) {
    <tr>
        <td>@item.Item</td>
        <td>@item.CreationDate</td>
        <td>
            @if (@item.IsDone) { 
                <a class="isDone" href="#" data-tododb-itemid="@item.ToDoItemID">Complated (Mark as Not Complated)</a>
            } else { 
                <a class="isDone" href="#" data-tododb-itemid="@item.ToDoItemID">Not Complated (Mark as Complated)</a>
            }
        </td>
    </tr>   
}

With this change, we make the DOM ready for the JQuery. Let’s look at the JQuery code for the toggle action :

        (function () {
            $(function () {

                function toggleIsDone(e, element) {

                    var itemId = element.attr("data-tododb-itemid");
                    var d = "itemId=" + itemId;
                    var actionURL = '@Url.Action("toogleIsDone", "ToDo")';

                    $("#ajax-progress-dialog").dialog("open");

                    $.ajax({
                        type: "POST",
                        url: actionURL,
                        data: d,
                        success: function (r) {
                            $("#to-do-db-list-container").html(r.data);
                        },
                        complete: function () {
                            $("#ajax-progress-dialog").dialog("close");
                            $(".isDone").bind("click", function (event) {
                                toggleIsDone(event, $(this));
                            });
                        },
                        error: function (req, status, error) {
                            //do what you need to do here if an error occurs
                            $("#ajax-progress-dialog").dialog("close");
                        }
                    });

                    e.preventDefault();
                }

                $(".isDone").bind("click", function(e) {
                        toggleIsDone(e, $(this));
                });

            });
        })();

Let’s bring that code down into pieces. First, we bind toggleIsDone(e, element) as a click function to every element whose class attribute is ‘isDone’ and we know that they are our toggle anchors. On the toggleIsDone function, we will grab the itemId of the clicked item from data-tododb-itemid attribute of clicked anchor. Then, we will set the itemId as parameter on d variable.

Look at the actionURL variable. What happens there is that : we assigning the URL of toogleIsDone action of ToDo controller.

Before we begin our AJAX call, we simply fire up our loading dialog to display that we are doing some stuff.

On the AJAX call, we make a post request to actionURL and we are passing the d variable as data. We know that we will get back a JSON result which contains a data property and on success event of the call we simply change the content of to-do-db-list-container element with the new one which we have received from the server as JSON result.

Just before we step out the success event, we do very tricky stuff there. It is tricky in this case and hard to figure it out if you are new to JQuery. I will try to explain what we did there. We bind toggleIsDone(e, element) as a click function to every element whose class attribute is ‘isDone’. The weird thing is the fact that we have done the same just after the DOM has loaded. So, why the heck do we do that? We have bind the specified function to specified elements just after the DOM has loaded. That’s fine. Then, we have update the entire content of to-do-db-list-container div and the all click event that we have bind has been cleared out. In order not to lose the functionality, we have bind them again.

This kind of an Inception way is the best way that I come up with for this functionality and if you thing there is a better one, let me know.

On complete event, we made sure to close our loading dialog.

At the end of the code, we call a function called preventDefault() for the event. What this does is to prevent the anchor to do its default function which would be the append the # to the URL. Not necessary here but it is kind of nice to use here though.

So far, we have completed our work on client side code and lastly, we need to implement the server side function which updates the database according to parameters and sends a JSON result back to the client.

Before we do that we need to use Nuget here to bring down a very small package called TugberkUg.MVC which will have a Controller extension for us to convert partial views to string inside the controller.

image

image

The complete code of out ToDoController is as indicated below :

using System.Linq;
using System.Web.Mvc;
using TugberkUg.MVC.Helpers;
using System.Data.Objects;
using System.Data;

namespace JQueryAJAXToDoListMVCApp.Controllers
{
    public class ToDoController : Controller {

        private readonly Models.ToDoDBEntities _entities = new Models.ToDoDBEntities();

        public ActionResult Index() {

            var model = _entities.ToDoTBs;

            return View(model);
        }

        [HttpPost]
        public ActionResult toogleIsDone(int itemId) {

            //Getting the item according to itemId param
            var model = _entities.ToDoTBs.FirstOrDefault(x => x.ToDoItemID == itemId);
            //toggling the IsDone property
            model.IsDone = !model.IsDone;

            //Making the change on the db and saving
            ObjectStateEntry osmEntry = _entities.ObjectStateManager.GetObjectStateEntry(model);
            osmEntry.ChangeState(EntityState.Modified);
            _entities.SaveChanges();

            var updatedModel = _entities.ToDoTBs;

            //returning the new template as json result
            return Json(new { data = this.RenderPartialViewToString("_ToDoDBListPartial", updatedModel) });
        }

        protected override void Dispose(bool disposing) {

            _entities.Dispose();
            base.Dispose(disposing);
        }

    }
}

When you look inside the toogleIsDone method, you will see that after the necessary actions are completed, we will pass a model to our partial view which we have created earlier, render it and finally return it to the client as JSON. Why we return it as JSON instead of content is a totally subjective question in my opinion. For me, the advantage of JSON result is to be able to pass multiple values. For example, we would pass the result as follows if we needed :

            return Json(
                new { 
                    CustomMessage = "My message", 
                    data = this.RenderPartialViewToString("_ToDoDBListPartial", updatedModel) 
                });

Now when we compile our project and run it, we will see a working application :

image image image

Also, here is a quick video of a working example :

Summary

What we need to get out of from this blog post is to see that what we are capable of doing with a little effort for very usable and user friendly web pages. Also, we can visualize how things fit together and flow on your project. There are lots of way of making calls to your server from client side code and lots of them have its own pros and cons.

I hope that this blog post helps you, even a little, to solve a real world problem with your fingers Smile

TinyMCE HTML Text Editior & ASP.NET MVC - Setting It Up Has Become Easy With Nuget

One of the best Javascript WYSIWYG Editors TinyMCE is now up on Nuget live feed. How to get TinyMCE through Nuget and get it working is documented in this blog post.
2011-09-07 06:15
Tugberk Ugurlu


tinymce-logoOverview of the Process

Couple of weeks ago, I was setting up a new project and I have created a folder called ‘lib’ inside the $(SolutionDir) as usual to put all the dependencies that I am going to be using for my project (.Net libraries, JavaScript libraries, etc.).

Then, I go to http://www.tinymce.com/ to grab the latest version of TinyMCE which is an awesome Javascript WYSIWYG Editor. This action popped up a balloon inside my head that tells me I had been doing this stuff over and over again for 80% of the projects that I have created. So this hits me hard and I thought I should automate this process. In order to do that, I’ve created an internal Nuget package just for myself to pull the TinyMCE package with plugins. Even, I have created EditorTemplates so that I could just give my model a hint to use the template.

That worked pretty well for me but don’t miss the point here. That worked pretty well only for me. Not for John, Denis, Adam and so on. After I thought this, I have come across a blog post about TinyMCE integration on ASP.NET MVC 3 (The blog post is in Turkish). Remember the balloon which popped up inside my head? This blog post widened that balloon and it hit me harder this time. The process which has been documented there is a very well working sample but well…, it looked more like a poor man’s TinyMCE integration for me. (The article was nice but it wasn’t following the DRY way)

After that, I have decided to enhance my packages to push them to live Nuget feed. So, I have contacted with the package admins on their forum :

TinyMCE Nuget Package

@Spocke has replied my post in a short time and gave me a go ahead to push the package to live Nuget feed. I am not going to get into details of how I created the package. Mostly, I will show how to set up your environment to get TinyMCE working in a short time.

TinyMCE into an ASP.NET MVC project

tinymce-Nuget-packages-of-mine

It is now easy to get TinyMCE package to your project with Nuget. It’s even easier to get it working with ASP.NET MVC. In this post, I am going show you the easiest way to get it work ASP.NET MVC but I hope I am going to cover for Web Forms as well in near future.

There are several packages which are related to TinyMCE that I have pushed to live Nuget feed as you can see in the picture left hand side. (This list might extend in the future) Briefly the packages are :

TinyMCE : The main package which holds the infrastructure .js files of the library and plugings. This package has no dependency at all.

TinyMCE.JQuery : Holds the JQuery integration files for TinyMCE. This package depends on TinyMCE and JQuery packages.

TinyMCE.MVC : This package holds the ASP.NET MVC EditorTemplates for TinyMCE. This package depends on TinyMCE package.

TinyMCE.MVC.JQuery : Holds the ASP.NET MVC EditorTemplates for TinyMCE.JQuery. This package depends on TinyMCE.JQuery package.

TinyMCE.MVC.Sample : Holds a sample ASP.NET MVC mini Application (it is all just a model, a controller and a view) for TinyMCE. This package depends on TinyMCE.MVC package so it uses EditorTemplates to illustrate a sample.

TinyMCE.MVC.JQuery.Sample : This package holds a sample ASP.NET MVC mini Application (it is all just a model, a controller and a view) for TinyMCE.JQuery. This package depends on TinyMCE.MVC.JQuery package so it uses EditorTemplates to illustrate a sample.

How to get TinyMCE work on and ASP.NET MVC project

I would like set the boundaries here :

  • This will demonstrate the process of integrating TinyMCE to an ASP.NET MVC application.
  • I will use the JQuery one because it has more downloads on Nuget Smile
  • I will work with the TinyMCE.JQuery.MVC package to pull down all the TinyMCE stuff along with ASP.NET MVC EditorTemplates.

Always first thing to go is File > New Project > ASP.NET MVC 3 Web Application.

In order to make it more clear, I have created a very simple BlogPost model to work with. First, I am going to show you the way without TinyMCE then later we will bring it down through Nuget.

The model looks like as below :

    public class BlogPost {

        public string Title { get; set; }
        public DateTime PostedOn { get; set; }
        public string Tags { get; set; }
        public string Content { get; set; }

    }

Then I created a controller to create a new blog post (assume here this model is related to database). The controller is simple :

using System.Web.Mvc;
using TinyMCEJQueryMVCNuget.Models;

namespace TinyMCEJQueryMVCNuget.Controllers {

    public class BlogPostController : Controller {

        public ActionResult Create() {

            return View();
        }

        [HttpPost, ActionName("Create")]
        public ActionResult Create_post(BlogPost model) {

            ViewBag.HtmlContent = model.Content;

            return View(model);
        }

    }
}

It basically does noting. Just getting the model on the http post event and pushing it back to the view with a ViewBag property.

Here is what some portion of our view looks like :

@using (Html.BeginForm()) {
    
    @Html.ValidationSummary(true)

    <fieldset>
        <legend>BlogPost</legend>

        <div class="editor-label">
            @Html.LabelFor(model => model.Title)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Title)
            @Html.ValidationMessageFor(model => model.Title)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.PostedOn)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.PostedOn)
            @Html.ValidationMessageFor(model => model.PostedOn)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.Tags)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Tags)
            @Html.ValidationMessageFor(model => model.Tags)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.Content)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Content)
            @Html.ValidationMessageFor(model => model.Content)
        </div>

        <p>
            <input type="submit" value="Create" />
        </p>

        <p>
            Posted Content : @ViewBag.HtmlContent
        </p>

    </fieldset>
}

When we open it up, we will see nothing fancy there :

image

When we post it, we will get this result :

image

So, we got this baby working. Let’s improve it. What we need here is to give the blogger a real blogging experience. In order to do that, we need a text editor so that we could enter our content pretty easily.

First thing is to pull down the TinyMCE.JQuery.MVC package over the wire.

install-package

When you start installing the package, your solution will have a movement so don’t freak out Smile

image

imageSo now we have our package installed, we are ready to make some changes on our model. When you go to ~/Views/Shared/EditorTemplates folder on your solution, you will see that there is a cshtml file there called tinymce_jquery_full.cshtml. This partial view enables you to view your model property with TinyMCE editor.

I am not going to go inside this file and explain how to do this (however, it is pretty simple). It is entirely an another topic.

What I would like to point out here is this : if you are working with this package (TinyMCE.JQuery.MVC), you need to have JQuery referenced on your file. We have our JQuery referenced on our _Layout.cshtml file so we do not need to do anything else.

As I got the information from the project admins, TinyMCE can work with JQuery 1.4.3 and after. You don’t need to worry about that as well. Nuget will resolve the dependency without you knowing.

Change to Our Model

To get it work, we need to change our model as follows :

using System;
using System.ComponentModel.DataAnnotations;
using System.Web.Mvc;

namespace TinyMCEJQueryMVCNuget.Models {

    public class BlogPost {

        public string Title { get; set; }
        public DateTime PostedOn { get; set; }
        public string Tags { get; set; }

        [UIHint("tinymce_jquery_full"), AllowHtml]
        public string Content { get; set; }

    }
}

What UIHint attribute does here is to tell the framework to use tinymce_jquery_full editor template instead of the default one. AllowHtml is also there to allow html string to pass from your browser to the server. Build you project and run it again and then you should see a page similar to following one:

image

If you are unable to see this when you run your application, this can be related to several things. First thing I would do is to check if the Content property is used with EditorFor instead of another Html Helpers :

        <div class="editor-label">
            @Html.LabelFor(model => model.Content)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Content)
            @Html.ValidationMessageFor(model => model.Content)
        </div>

The second thing would be a JavaScript error related to misconfiguration or a wrong library reverence. Check your browser console for any JavaScript errors for that.

Now when we post it back to server, we will get it back as :

image

Very nice. Html has been created for us behind the scenes.

It displays it as encoded html because we didn’t specify to view as raw html. In order to do that, just use @Html.Raw.

I hope this will help you to automate some portion of your project as well.

Tags