You're correct, I had exact that issue.
The best way I've seen is to use the CreatingPage event. Though a better practice is to create an InitializationModule insted of bloating Global.asax (Single responsibility)
Read more on my blog: http://talk.alfnilsson.se/2013/03/17/simplifying-event-handling-in-episerver-7-cms/
Thank you Alf. At least then I can stop trying to find a better way. I suppose I should use the SavingPage also to make sure the user hasn't cleared the property of it's value since making this property required is out of the question.
Do you mean that making the property "MainHeading" required is out of the question? If so, why?
Well, if I can't set it to the same value as the page name in the SetDefaultValues method, how can I then give it its value before creating the page? When the CreatingPage is firing in global.asax I need to have already passed the validation or am i missing something?
Ah, now I see what you mean.
Instead of having an event on the SavingPageEvent, I would create a custom validator.
Though you could consider if it would be better to have a fallback to PageName if the editor did not specify a MainHeading instead of forcing a MainHeading.
Some information about creating your own validator:
http://www.episerver.com/About-Us/holidaycountdown2012/5-Validation-attributes-in-EPiServer-7/
http://www.david-tec.com/2012/06/EPiServer-7-Preview---Using-validation-attributes/
To be honest the reason I choose to go this way was because i didnt know how to make a fallback in a good looking way in MVC since im not that familiar with it yet. In webforms I would just use a episerver property webcontrol and set the property name to either pagename or mainheading, depending on if the mainheading was set. As i saw it in mvc i would have to use if statements in the cshtml file to see if the property was set and then load the appropriate property. Since i thought that would look ugly and that it wouldnt hurt if mainheading was required i went this way instead
Either you could add logic to the GET in your public virtual string MainHeading { get; set; }
But that kind of makes the Model/PageData object have more responsibility than it should.
Otherwise you can create a HtmlHelper that can take fallback parameters.
For example @Html.PropertyForWithFallbacks(page => m.MainHeading, page => page.PageName) or similar..
Take a look at the PropertyFor Extensionmethod with DotPeek, Reflector or your favourite decompiler.
A simpler version would be to not have the lambda expressions:
@Html.PropertyForWithFallbacks(page, "MainHeading", "PageName") and in the backend use page[propertyNameVariable]
Not that when using page["PropertyName"] does only take the value of the property stored in the database and does not use the logic that might have been added to the GET in the PageType class
What would the best practice way be to set a property value to the same as the page name? At the moment I did this in Global.asax:
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
DataFactory.Instance.CreatingPage += Instance_CreatingPage;
}
void Instance_CreatingPage(object sender, PageEventArgs e)
{
var page = e.Page as SitePageData;
if (page != null && page.MainHeading == null)
page.MainHeading = page.PageName;
}
However, I feel like their must be a better way to do this. I First tried using SetDefaultValues on the SitePageData class and from there set to MainHeading to PageName but since this fires before the page is created, the page name was still empty.
The drawback of the way I'm doing it now is that I can't set this property to required as the code in global won't fire until we actually create the page and episerver will stop us from saving it before that.