5

How do I get the name, set in the CMS, of a certain block in an MVC view?

I guess that it should be @Model.Name but I can't find it.

Ted Nyberg
  • 7,001
  • 7
  • 41
  • 72
rablentain
  • 6,641
  • 13
  • 50
  • 91

3 Answers3

7

You have to cast your block instance to IContent to access the Name property.

For details on why, you can have a look at: Episerver - Why BlockData doesn't implement IContent

Community
  • 1
  • 1
Ted Nyberg
  • 7,001
  • 7
  • 41
  • 72
4

The syntax to get the Name property is

(Model as IContent).Name

or

((IContent)Model).Name

Be careful with this cast as handling a Block which is a property as opposed to a ContentReference will not work and throws an exception.

Robin French
  • 675
  • 6
  • 17
  • 2
    Good point! I think your first example should be `var blockName = (Model as IContent)?.Name ?? "Local block"` to avoid a potential null reference exception. To use the null-coalescing operator in a Razor view you need to enable C# 6+ with the `Microsoft.CodeDom.Providers.DotNetCompilerPlatform` NuGet package, though. – Ted Nyberg Jul 12 '18 at 14:06
  • Yeah, you are right about that. I do find though that the cast exception tends to counter the risk of null reference exception. The idea is that if the object was null after the cast then the cast itself would have thrown an exception. For completeness though you're absolutely right and there should be a null check on it. ReSharper would put a possible null reference warning on that line without one. It's a shame you can't use ? operator in razor without that package as it makes the null checks much tidier! – Robin French Jul 12 '18 at 20:01
  • It's weird that you have to go to these lengths to get the block name as well. Especially since using the block name is such a useful fall back to avoid putting a requirement on a title field so it can be left blank and the title defaults to the block name. – Robin French Jul 12 '18 at 20:04
  • 1
    I think the architecture makes sense, but I see what you mean. We derive most of our block types - especially those used in content areas - from a custom base class with a `Name` property, so that it's accessible without the extra hassle. :) – Ted Nyberg Jul 12 '18 at 20:44
  • That would be very useful but I guess the issue is you can't get the `Name` without tying the object to `IContent`, which is what they were trying to avoid. I'm considering an extension method for a base block type to return the block as `IContent` since I seem to be writing this bit of code quite a lot! – Robin French Jul 12 '18 at 22:03
1

If you want to display the name in the view - you can cast the model inside PropertyFor: @Html.PropertyFor(m => ((IContent)m).Name)