Sorted By: Tag (razor)

ASP.NET MVC Code Review #2 - A Way of Working with Html Select Element (AKA DropDownList) In ASP.NET MVC

This is the #2 of the series of blog posts which is about some core scenarios on ASP.NET MVC: A Way of Working with Html Select Element (AKA DropDownList) In ASP.NET MVC
2011-12-30 14:28
Tugberk Ugurlu


This is the #2 of the series of blog posts which is about some core scenarios on ASP.NET MVC. In this one, code review #2, I will try to show you the best way of working with Html Select element (AKA DropDownList) in ASP.NET MVC. Here is the code:

Repository Class which generates the dummy data for the demo:

public class ProductCategory {

    public int CategoryId { get; set; }
    public string CategoryName { get; set; }
}

public class ProductCategoryRepo {

    public List<ProductCategory> GetAll() {

        List<ProductCategory> categories = new List<ProductCategory>();

        for (int i = 1; i <= 10; i++) {

            categories.Add(new ProductCategory { 
                CategoryId = i,
                CategoryName = string.Format("Category {0}", i)
            });
        }

        return categories;
    }
}

Controller:

public class SampleController : Controller {

    private readonly ProductCategoryRepo productCategoryRepo = 
         new ProductCategoryRepo();

    public ActionResult Index() {

        registerProductCategorySelectListViewBag();
        return View();
    }

    private void registerProductCategorySelectListViewBag() {

        ViewBag.ProductCategorySelectList = 
            productCategoryRepo.GetAll().Select(
                c => new SelectListItem { 
                    Text = c.CategoryName,
                    Value = c.CategoryId.ToString()
                }
            );
    }
}

View:

@{
    ViewBag.Title = "HTML Select List Sample";
}

<h2>HTML Select List Sample</h2>

<p>
    <strong>Product Categories:</strong>
</p>
<p>
    @Html.DropDownList(
        "ProductCategoryId", 
        (IEnumerable<SelectListItem>)ViewBag.ProductCategorySelectList
    )
</p>

Let’s see what it generates for us:

Output HTML of Select element:

<select id="ProductCategoryId" name="ProductCategoryId">
    <option value="1">Category 1</option>
    <option value="2">Category 2</option>
    <option value="3">Category 3</option>
    <option value="4">Category 4</option>
    <option value="5">Category 5</option>
    <option value="6">Category 6</option>
    <option value="7">Category 7</option>
    <option value="8">Category 8</option>
    <option value="9">Category 9</option>
    <option value="10">Category 10</option>
</select>

Just like what I expected. On the controller, you see that I newed up SelectListItem classes and pass them to the view through the ViewDataDictionary. SelectListItem class works nicely with DropDownList and DropDownListFor Html helpers within ASP.NET MVC as you see inside the view code above.

So, don’t try to reinvent the wheel and don’t get into for and foreach loops in order just to create a select element. SelectListItem has been put inside the library just for this purpose and leverage it.

ASP.NET MVC Code Review #1 - File Upload With HttpPostedFileBase Class

This is #1 of the series of blog posts which is about some core scenarios on ASP.NET MVC: File Upload With HttpPostedFileBase Class
2011-12-29 21:25
Tugberk Ugurlu


Today, I decided to change my blogging style a little bit. I always try to write posts which contains detailed information about the subject but I realized that it prevents me from writing much more useful things. So, from now on, I will drop a bunch of code on the screen and talk about that briefly.

This is the beginning of the series of blog posts which is about some core scenarios on ASP.NET MVC. In this one, code review #1, I will give you an example on how to get file upload functionality working in ASP.NET MVC. Here is the code:

Controller:

public class SampleController : Controller {

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

    [ActionName("Index")]
    [ValidateAntiForgeryToken, HttpPost]
    public ActionResult Index_post(HttpPostedFileBase File) {

        //Check if the file is not null and content length is bigger than 0
        if (File != null && File.ContentLength > 0) {

            //Check if folder is there
            if(!System.IO.Directory.Exists(Server.MapPath("~/Content/PostedFiles")))
                System.IO.Directory.CreateDirectory(
                    Server.MapPath("~/Content/PostedFiles")
                );

            //Set the full path
            string path = System.IO.Path.Combine(
                Server.MapPath("~/Content/PostedFiles"),
                System.IO.Path.GetFileName(File.FileName)
            );

            //Save the thing
            File.SaveAs(path);

            TempData["Result"] = "File created successfully!";
        }

        //RedirectToAction so that we can get rid of so-called "Form Resubmission"
        return RedirectToAction("Index");
    }

}

View:

@{
    ViewBag.Title = "File Upload Sample";
}
<h2>File Upload Sample</h2>

@if (TempData["Result"] != null) { 
    <ul>
        <li>@TempData["Result"]</li>
    </ul>
}

@using (Html.BeginForm("index", "sample", 
    FormMethod.Post, new { enctype = "multipart/form-data" })) {
 
    @Html.AntiForgeryToken()
    
    <input type="file" name="File" />
    <p>
        <input type="submit" value="Upload" />
    </p>
}

Actually, code explains itself nicely here but I see one thing to worth pointing out here. HttpPostedFileBaseModelBinder class from System.Web.Mvc namespace is the class which binds a model to a posted file. So, the parameter (which is type of HttpPostedFileBase) of the Index_post method receives the posted file.

Pretty neat stuff. Hope you enjoy it.

Donut Hole Caching In ASP.NET MVC by Using Child Actions and OutputCacheAttribute

This blog post demonstrates how to implement Donut Hole Caching in ASP.NET MVC by Using Child Actions and OutputCacheAttribute
2011-10-30 09:40
Tugberk Ugurlu


homer-and-donut

One of the common issues of web applications is performance and serving the same content over and over again for hours, days, even months is certainly effecting the performance of our web applications. This is where server side caching comes in handy. But sometimes the whole page we are scripting on the server side is going to be static for hours and sometimes some portion of it.

The first one, caching the whole page, is sort of easy with almost any web development frameworks. The second one, caching a portion of your web page, is the tricky one.

Phil Haack blogged about Donut Hole Caching in ASP.NET MVC a while back but it is a little outdated. In this quick blog post, I will try to show you the easiest way of implementing this feature with ASP.NET MVC.

Use Cases

So, where might we need this Donut Hole Caching thing? For example, if you are listing categories on the side bar, you probably gathering those categories from a database. Add the fact that you render this part on every single page of your web application, it is a waste of time if your category list is not so dynamic. So, you may want to cache the category list part of the page so that you don’t go to your database every single time.

How to Do

In ASP.NET MVC framework, we can cache the whole controller action with OutputCacheAttribute which represents an attribute that is used to mark an action method whose output will be cached according to MSDN. This is perfect but wait a second. We do not want to cache the entire action, we just want to cache the portion of it. This is where ChildActionExtensions.Action method, which invokes a child action method and returns the result as an HTML string, plays a huge role. Let me show you how these parts of the framework play nice together.

Have a look at the below controller action :

[ChildActionOnly]
[OutputCache(Duration=60)]
public ActionResult sampleChildAction() {

    //Put the thread at sleep for 3 seconds to see the difference.
    System.Threading.Thread.Sleep(3000);

    //Also pass the date time from here just to see that it is comming from here.
    ViewBag.DateTime = DateTime.Now.ToString("dd.MM.yyyy HH:mm.ss");

    return View();
}

A simple controller action method which returns ActionResult, nothing fancy going on except for ChildActionOnlyAttribute which represents an attribute that is used to indicate that an action method should be called only as a child action. Let’s look at the sampleChildAction view and I will try to explain ChildActionOnlyAttribute function after that.

@{
    Layout = null;
}

<p>
    This portion of the web page was scripted on <strong>@ViewBag.DateTime</strong> and I will be cached for <strong>60</strong> seconds.
</p>

This html will be a part of our web page which will be cached. It doesn’t mean anything by itself but we have created an action for this view which means that we can call this page directly from a browser. ChildActionOnlyAttribute exactly prevent users to call this kind of actions. You do not need to implement this attribute there but it is nice to know that it is there for us.

The controller action which will render the whole page is so simple as below and doesn’t require any special thing for us to implement in order caching to work.

public ActionResult Index() {

    return View();
}

Let’s also look at the view implementation :

@{
    ViewBag.Title = "Donut Hole Caching Sample";
}

<h2>Donut Hole Caching Sample</h2>

<h3>Cached</h3>

<div>
    @Html.Action("sampleChildAction", 
      new { controller = "Sample", Area = "DonutHoleCaching" }
    )
</div>

<h3>Normal</h3>

<div>
    <p>
        This portion of the web page was scripted on <strong>@DateTime.Now.ToString("dd.MM.yyy HH:mm.ss")</strong>
    </p>
</div>

What we are doing here is that rather than putting the part, which we would like to cache, directly here, we are calling it as child action. So, the framework will treat the child action as it does for normal action methods.

When we first call it, we will see something like below :

image

While I was calling this page, I was on hold for 3 seconds because we have put the thread at sleep for 3 seconds on our child action method to feel the difference as you can see on above code in order.

When I make the second call, I got something like this and I wasn’t on hold for 3 seconds :

image

Did you notice the time difference? This proves that if the cache is valid, our child action method won’t be rendered again. It will serve from the cache. Awesome, ha?

I decided to create an ASP.NET MVC project called MvcMiracleWorker for this kind of small samples. You can find the complete source code from GitHub : https://github.com/tugberkugurlu/MvcMiracleWorker

Behave well, use ASP.NET MVC Winking 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.

Best Solution to My Web Site With ASP.Net MVC 3 & Razor View Engine!

Recently, I have been playing around with MVC a lot and I decided to use the latest MVC tecnology on my web site...
2010-12-09 20:45
Tugberk Ugurlu


tugberk-ugurlu-com-commercial-logo-2.PNGRecently, I have been playing around with ASP.Net MVC 3.0 a lot and I decided to use the latest MVC tecnology on my web site and I have just updated my web site with MVC 3.0 and I used Razor as view engine.

I have used NuGet a lot with this project and I cannot imagine life without NuGet now :D This must be the major side affect of the NuGet, I guess :)

I have implemented lots of new features and I realized that I have improved a lot because now I consider the fact that people needs to reach the information in a very easy way. So I created tags section, archive section and internal search.

Also, I noticed that registration is lame and so I enabled comments to anyone. You do not need to log into system in order to leave a comment, just do it.

I thought that deployment would be the most annoying part since I have shared hosting (because no one is willing to support me :)) but the Visual Studio 2010 make it so easy for me with publish web site button! I just configured the publish wizard and the IDE did all the work. The hostng firm doesn't support the MVC 3 as I imagined so I need to do a little trick there. I coppied the essential dll files for MVC 3 application into my bin folder.

Ok, guys. Let's see how long I could stand up with this web site :)

Tags