Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

adding warning note on v13 about removal of UmbracoApiController #6055

Merged
merged 1 commit into from
Apr 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions 13/umbraco-cms/extending/database.md
Original file line number Diff line number Diff line change
Expand Up @@ -283,3 +283,7 @@ public class BlogCommentsApiController : UmbracoApiController
}
}
```

{% hint style="warning" %}
The above example uses UmbracoApiController which is removed in Umbraco 14. The replacement for this is UmbracoManagementApiControllerBase.
{% endhint %}
4 changes: 4 additions & 0 deletions 13/umbraco-cms/extending/section-trees/trees/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,10 @@ The first node in the tree is referred to as the **Root Node**. You can customis

### Implementing the Tree

{% hint style="warning" %}
The example below uses UmbracoApiController which is removed in Umbraco 14. The replacement for this is UmbracoManagementApiControllerBase.
{% endhint %}

```csharp
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,7 @@
The following is an example of a Partial View for a Block Type of type `MyElementTypeAliasOfContent`.

{% code title="MyElementTypeAliasOfContent.cshtml" %}

```csharp
@inherits Umbraco.Cms.Web.Common.Views.UmbracoViewPage<Umbraco.Cms.Core.Models.Blocks.BlockGridItem>;

Expand All @@ -252,11 +253,13 @@
@* Render the block areas *@
@await Html.GetBlockGridItemAreasHtmlAsync(Model)
```

{% endcode %}

If you are using ModelsBuilder, you can make the property rendering strongly typed by letting your view accept a model of type `BlockGridItem<T>`. For example:

{% code title="MyElementTypeAliasOfContent.cshtml" %}

```csharp
@inherits Umbraco.Cms.Web.Common.Views.UmbracoViewPage<Umbraco.Cms.Core.Models.Blocks.BlockGridItem<ContentModels.MyElementTypeAliasOfContent>>;
@using ContentModels = Umbraco.Cms.Web.Common.PublishedModels;
Expand All @@ -267,6 +270,7 @@
@* Render the block areas *@
@await Html.GetBlockGridItemAreasHtmlAsync(Model)
```

{% endcode %}

#### Stylesheet
Expand Down Expand Up @@ -296,6 +300,7 @@
The following example mimics the built-in rendering mechanism for rendering Blocks using Partial Views:

{% code title="View.cshtml" %}

```csharp
@inherits Umbraco.Cms.Web.Common.Views.UmbracoViewPage
@using Umbraco.Cms.Core.Models.Blocks
Expand All @@ -314,11 +319,13 @@
}
}
```

{% endcode %}

If you do not want to use Partial Views, you can access the block item data directly within your rendering:

{% code title="View.cshtml" %}

```csharp
@inherits Umbraco.Cms.Web.Common.Views.UmbracoViewPage
@using Umbraco.Cms.Core.Models.Blocks
Expand Down Expand Up @@ -348,6 +355,7 @@
}
}
```

{% endcode %}

## Write a Custom Layout Stylesheet
Expand Down Expand Up @@ -457,15 +465,19 @@
## Creating a Block Grid programmatically

In this example, we will be creating content programmatically for a "spot" Blocks in a Block Grid.

1. On a document type add a property called **blockGrid**.
2. Then add as editor **Block Grid**.
2. Then add as editor **Block Grid**.
3. In the Block Grid add a new block and click to **Create new Element Type**
4. Name this element type **spotElement** with the following properties:

- a property called **title** with the editor of **Textstring**
- a property called **text** with the editor of **Textstring**
5. Then on the **Settings model** click to add a new Setting.
* a property called **text** with the editor of **Textstring**

Check warning on line 475 in 13/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/block-editor/block-grid-editor.md

View workflow job for this annotation

GitHub Actions / runner / vale

[vale] reported by reviewdog 🐶 [UmbracoDocs.ListStart] Start each option with a capital letter. Raw Output: {"message": "[UmbracoDocs.ListStart] Start each option with a capital letter.", "location": {"path": "13/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/block-editor/block-grid-editor.md", "range": {"start": {"line": 475, "column": 1}}}, "severity": "WARNING"}

5. Then on the **Settings model** click to add a new Setting.
6. Then click to **Create new Element Type**.
7. Name this element type **spotSettings** with the following properties:

- a property called **featured** with the editor of **True/false**.

![Block Grid - Block Configuration](../../../images/BlockEditorConfigurationProgramatically.png)
Expand Down Expand Up @@ -536,6 +548,7 @@
8. First and foremost, we need models to transform the raw data into Block Grid compatible JSON. Create a class called **Model.cs** containing the following:

{% code title="Models.cs" lineNumbers="true" %}

```csharp
using Newtonsoft.Json;
using Umbraco.Cms.Core;
Expand Down Expand Up @@ -620,11 +633,13 @@
public Dictionary<string, object> Data { get; }
}
```

{% endcode %}

9. By injecting [ContentService](../../../../../reference/management/services/contentservice/) and [ContentTypeService](../../../../../reference/management/services/contenttypeservice/) into an API controller, we can transform the raw data into Block Grid JSON. It can then be saved to the target content item. Create a class called **BlockGridTestController.cs** containing the following:

{% code title="BlockGridTestController.cs" lineNumbers="true" %}

```csharp
using Microsoft.AspNetCore.Mvc;
using My.Site.Models;
Expand Down Expand Up @@ -715,8 +730,13 @@
}
}
```

{% endcode %}

{% hint style="warning" %}
The above example uses UmbracoApiController which is removed in Umbraco 14. The replacement for this is UmbracoManagementApiControllerBase.
{% endhint %}

For the above code `IContent? content = _contentService.GetById(1203);` change the id with your content node that is using the Block Grid.

10. In order to test this implementation, run the project and add `/umbraco/api/blockgridtest/create` after your domain name. If the result shows as **Saved** then check your content node and you will see the 2 spotElement contents.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,10 @@ public class CreateImageCropperValuesController : UmbracoApiController
}
```

{% hint style="warning" %}
The above example uses UmbracoApiController which is removed in Umbraco 14. The replacement for this is UmbracoManagementApiControllerBase.
{% endhint %}

If you use Models Builder to generate source code (modes `SourceCodeAuto` or `SourceCodeManual`), you can use `nameof([generated property name])` to access the desired property without using a magic string:

```csharp
Expand Down
6 changes: 5 additions & 1 deletion 13/umbraco-cms/fundamentals/code/debugging/logging.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ The default location of this file is written to `umbraco/Logs` and contains the

## Video overview

{% embed url="https://youtu.be/PDqIRVygAQ4" %}
{% embed url="<https://youtu.be/PDqIRVygAQ4>" %}
Watch this video to get an overview of how to view and manage logs and logfiles for your Umbraco CMS website.
{% endembed %}

Expand Down Expand Up @@ -56,6 +56,10 @@ Umbraco writes log messages, but you are also able to use the Umbraco logger to

Here is an example of using the logger to write an Information message to the log which will contain one property of **Name** which will output the name variable that is passed into the method

{% hint style="warning" %}
The example below uses UmbracoApiController which is removed in Umbraco 14. The replacement for this is UmbracoManagementApiControllerBase.
{% endhint %}

```csharp
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
Expand Down
17 changes: 11 additions & 6 deletions 13/umbraco-cms/implementation/controllers.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ All implementations of Umbraco API Controllers inherit from the base class: `Umb

For details on using Umbraco API Controllers, see the [Umbraco API Controllers](../reference/routing/umbraco-api-controllers/) article.

{% hint style="warning" %}
UmbracoApiController is removed in Umbraco 14. The replacement for this is UmbracoManagementApiControllerBase.
{% endhint %}

## Umbraco Authorized Controllers and Attributes

An Umbraco Authorized Controller is used when the controller requires member or user authentication (authN) and/or authorization (authZ). If either the `authN` or `authZ` fail, the controller will return a `401 - unauthorized response`.
Expand All @@ -45,14 +49,15 @@ An Umbraco Authorized Controller is used when the controller requires member or

The Umbraco Authorized controllers and attributes for Backoffice Users are:

* **MVC**
* **MVC**
There is no specific controller available to inherit from. We recommend inheriting from the basic `Umbraco.Cms.Web.Common.Controllers.UmbracoController` and applying the following attributes to your method:
- `[Authorize(Policy = AuthorizationPolicies.BackOfficeAccess)]`: Uses .NET authorization using the BackOfficeAccess policy. We recommend adding extra custom authorization policies for your endpoints.
- `[DisableBrowserCache]`: Tells the browser to not cache the result.
* `[Authorize(Policy = AuthorizationPolicies.BackOfficeAccess)]`: Uses .NET authorization using the BackOfficeAccess policy. We recommend adding extra custom authorization policies for your endpoints.
* `[DisableBrowserCache]`: Tells the browser to not cache the result.

Remember to [add a route](../reference/routing/authorized.md#defining-a-route) for your controller.

#### Example custom authorized backoffice MVC Controller
#### Example custom authorized backoffice MVC Controller

```csharp
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
Expand All @@ -73,8 +78,8 @@ The Umbraco Authorized controllers and attributes for Backoffice Users are:
}
}
```
* **WebAPI**

* **WebAPI**

A base class implementation for authorized auto-routed Umbraco API controllers is inherited from: `Umbraco.Cms.Web.BackOffice.Controllers.UmbracoAuthorizedApiController`. This controller inherits from `Umbraco.Cms.Web.Common.Controllers.UmbracoApiController` it is auto-routed. This controller is also attributed with `Umbraco.Cms.Web.Common.Attributes.IsBackOfficeAttribute` to ensure that it is routed correctly to be authenticated for the backoffice.

Expand Down
4 changes: 4 additions & 0 deletions 13/umbraco-cms/implementation/unit-testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,10 @@ public class PageSurfaceControllerTests

See [Reference documentation on UmbracoApiControllers](../reference/routing/umbraco-api-controllers/README.md#locally-declared-controller).

{% hint style="warning" %}
The example below uses UmbracoApiController which is removed in Umbraco 14. The replacement for this is UmbracoManagementApiControllerBase.
{% endhint %}

```csharp
public class ProductsController : UmbracoApiController
{
Expand Down
4 changes: 4 additions & 0 deletions 13/umbraco-cms/reference/cache/examples/tags.md
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,10 @@ public class TagsController : UmbracoApiController
}
```

{% hint style="warning" %}
The above example uses UmbracoApiController which is removed in Umbraco 14. The replacement for this is UmbracoManagementApiControllerBase.
{% endhint %}

`/umbraco/api/tags/getblogtags`:

![Result](images/response.png)
Expand Down
86 changes: 45 additions & 41 deletions 13/umbraco-cms/reference/common-pitfalls.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,10 @@ public class BadApiController : UmbracoApiController
}
```

{% hint style="warning" %}
The above example uses UmbracoApiController which is removed in Umbraco 14. The replacement for this is UmbracoManagementApiControllerBase.
{% endhint %}

This practice can cause memory leaks along with inconsistent data results when using this `_umbracoHelper` instance.

**Why?**
Expand Down Expand Up @@ -108,11 +112,11 @@ You create a menu on your Home page like:

```csharp
<ul>
<li><a href="@Model.Root().Url()">@Model.Root().Name</a></li>
@foreach (var node in Model.Root().DescendantsOrSelf().Where(x => x.Level == 2))
{
<li><a href="@node.Url()">@node.Name</a></li>
}
<li><a href="@Model.Root().Url()">@Model.Root().Name</a></li>
@foreach (var node in Model.Root().DescendantsOrSelf().Where(x => x.Level == 2))
{
<li><a href="@node.Url()">@node.Name</a></li>
}
</ul>
```

Expand All @@ -124,11 +128,11 @@ This can be re-written as:

```csharp
<ul>
<li><a href="@Model.Root().Url()">@Model.Root().Name</a></li>
@foreach (var node in Model.Root().Children)
{
<li><a href="@node.Url()">@node.Name</a></li>
}
<li><a href="@Model.Root().Url()">@Model.Root().Name</a></li>
@foreach (var node in Model.Root().Children)
{
<li><a href="@node.Url()">@node.Name</a></li>
}
</ul>
```

Expand All @@ -142,26 +146,26 @@ Here's a common pitfall that is seen. Let's continue the menu example, in this e

```csharp
<ul>
<li><a href="@Model.Root().Url()">@Model.Root().Name</a></li>
@foreach (var node in Model.Root().Children)
{
<li><a href="@node.Url()">@node.Name</a></li>
}
<li><a href="@Model.Root().Url()">@Model.Root().Name</a></li>
@foreach (var node in Model.Root().Children)
{
<li><a href="@node.Url()">@node.Name</a></li>
}
</ul>
```

The syntax `@Model.Root()` is shorthand for doing this: `Model.AncestorOrSelf(1)` which means it is going to traverse up the tree until it reaches an ancestor node with a level of one. As mentioned above, traversing costs resources and in this example, there are 3x traversals being done for the same value. Instead, this can be rewritten as:

```csharp
@{
var root = Model.Root();
var root = Model.Root();
}
<ul>
<li><a href="@root.Url()">@root.Name</a></li>
@foreach (var node in root.Children)
{
<li><a href="@node.Url()">@node.Name</a></li>
}
<li><a href="@root.Url()">@root.Name</a></li>
@foreach (var node in root.Children)
{
<li><a href="@node.Url()">@node.Name</a></li>
}
</ul>
```

Expand All @@ -178,11 +182,11 @@ Your views should rely only on the read-only data services such as `UmbracoHelpe
@inject IContentService _contentService

@{
// Services access in your views :(
var dontDoThis = _contentService.GetById(1234);
// Content cache access in your views
var doThis = Umbraco.Content(1234);
// Services access in your views :(
var dontDoThis = _contentService.GetById(1234);
// Content cache access in your views
var doThis = Umbraco.Content(1234);
}
```

Expand Down Expand Up @@ -284,17 +288,17 @@ You then run the following code to show to show the favorites
```csharp
@var recipeNode = Umbraco.TypedContent(3251);
@{
var recipeNode = Umbraco.Content(1234);
var recipeNode = Umbraco.Content(1234);
}

<ul>
@foreach (var recipe in recipeNode.Children
.Select(x => new RecipeModel(x, _publishedValueFallback))
.OrderByDescending(x => x.Votes)
.Take(10))
{
<li><a href="@recipe.Url()">@recipe.Name</a></li>
}
@foreach (var recipe in recipeNode.Children
.Select(x => new RecipeModel(x, _publishedValueFallback))
.OrderByDescending(x => x.Votes)
.Take(10))
{
<li><a href="@recipe.Url()">@recipe.Name</a></li>
}
</ul>
```

Expand Down Expand Up @@ -345,16 +349,16 @@ This is still not great though. There really isn't much reason to create a `Reci

```csharp
@{
var recipeNode = Umbraco.Content(1234);
var recipeNode = Umbraco.Content(1234);
}

<ul>
@foreach (var recipe in recipeNode.Children
.OrderByDescending(x => x.Value<int>("votes"))
.Take(10))
{
<li><a href="@recipe.Url()">@recipe.Name</a></li>
}
@foreach (var recipe in recipeNode.Children
.OrderByDescending(x => x.Value<int>("votes"))
.Take(10))
{
<li><a href="@recipe.Url()">@recipe.Name</a></li>
}
</ul>
```

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -403,6 +403,10 @@ public class RelationsController : UmbracoApiController
}
```

{% hint style="warning" %}
The above example uses UmbracoApiController which is removed in Umbraco 14. The replacement for this is UmbracoManagementApiControllerBase.
{% endhint %}

Notice the `x => new Relation()`? We need to make sure what we are returning can be serialized. Therefore the `Relation` class is:

```csharp
Expand Down
Loading
Loading