How to NOT use properties on Content Types

I’ve seen more and more examples on how to NOT use properties on your Content Types – setting visit/Request specific information to them.

My example below is a very harmless, but I’ve seen examples where the price for an e-com site is set like this!

How do you mean?

The example would be to display the visitor’s IP, which is common to be different for each request.

First of all we have a Block Type:

[ContentType(GUID = "5597f215-f5cc-4fd0-bcff-eb06a44fc343")
public class MyPage : PageData
{
    public string MyProperty { get; set; }
}

And the controller set’s the value:

public class MyPageController : PageControllerBase<MyPage>
{
    public ActionResult Index(MyPage currentPage)
    {
        currentPage.MyProperty = Request.UserHostAddress;
        return View(currentPage);
    }
}

And a view displays it:

@model MyPage
Name: @Html.PropertyFor(m => m.Name)
IP: @Model.MyProperty

But what’s the problem?

The problem is that each instance of MyPage is cached and could basically be referred to as “static” – when a value is set to MyProperty, the value is set for all visitors.

For example when visitor A visits from IP address “192.168.0.10”, MyProperty is set with the IP. When visitor B visits from “192.168.0.11”, MyProperty will still have the value from visitor A until the controller sets the IP from visitor B.

Or even worse: When the the visitor A comes to the view and MyProperty is rendered there is a chance that visitor B comes to the controller and sets a new value to MyProperty – so that the view will render the IP from visitor B.

I’m sorry for the crappy GIF, but hope you get the point ;)

properties

So what should I do?

Make sure that you have a specific class that contains your information and create a new instance of this class for each Request. For my example I would have a viewmodel instead. In Episerver projects the ViewModel could also contain the Content itself:

[ContentType(GUID = "5597f215-f5cc-4fd0-bcff-eb06a44fc343")
public class MyPage : PageData
{
}

public class MyPageViewModel
{
    public string MyProperty { get; set; }
    public MyPage CurrentPage { get; set; }
}

With the Controller

public class MyPageController : PageControllerBase<MyPage>
{
    public ActionResult Index(MyPage currentPage)
    {
        var viewModel = new MyPageViewModel
        {
             MyProperty = Request.UserHostAddress,
             CurrentPage = currentPage
        };
        return View(viewModel);
    }
}

And with the View

@model MyPageViewModel
Name: @Html.PropertyFor(m => m.CurrentPage.Name)
IP: @Model.MyProperty

Again this a simple example, but say you’re having an e-com solution and want to display the price. You don’t want to display other visitor’s prices don’t you? ;)

Advertisements

5 thoughts on “How to NOT use properties on Content Types

  1. I can only confirm that this might have really bad impact… Just a month ago, I made lots of bug fixes for a client related to this problem. I did the exact same solution as you describe, and I can confirm that it works like a charm :-)

  2. Daniel says:

    Love the gif :)

  3. vyan024 says:

    Always use ViewModel is one of true “best practice” that being heavily used nowadays, no matter whether it’s a CMS or bespoke application development.

    However, I still add some read-only properties to content-type for making our devs life easier, and haven’t experienced any issue.

    • Alf says:

      Thank you for your feedback! As long as your read-only property does not have a backing field or anything like that it would be OK for me :)

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: