Giter Site home page Giter Site logo

kontent-ai / boilerplate-net Goto Github PK

View Code? Open in Web Editor NEW
31.0 35.0 34.0 3.2 MB

Kontent.ai Boilerplate for development of ASP.NET Core MVC applications.

Home Page: https://kontent.ai/

License: MIT License

C# 85.85% CSS 3.48% JavaScript 1.16% HTML 8.56% PowerShell 0.43% Shell 0.53%
boilerplate aspnet-core asp-net-core mvc visual-studio hacktoberfest kontent-ai net6

boilerplate-net's People

Contributors

amoraitis avatar chariths avatar crnd avatar enngage avatar jancerman avatar kashifsoofi avatar kentico-branislavs avatar kontent-ai-bot avatar lextm avatar mirokentico avatar ondrejsevcik avatar petrsvihlik avatar robertgregorywest avatar robvanuden avatar sayedihashimi avatar sevitas avatar simply007 avatar tobiaskamenicky avatar tomasjurasek avatar winklertomas avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

boilerplate-net's Issues

Should we use a generic cache manager?

There are several cache manager libraries in the wild. One of the nice ones is https://github.com/MichaCo/CacheManager . It supports various caching technologies (incl. distributed ones) and is designed to store various types of data in the cache (not only Kentico Cloud data).

Would you welcome such a generic cache manager in our boilerplate?

Pros:

  • support for multiple caching technologies
  • state-of-the-art caching patterns implemented (failover mechanisms, geo-replication, etc.)
  • optimized for performance

Cons:

  • lack of support for cache item dependencies
  • lack of support for type dependencies (eg. if one content item is cached twice as both strongly-typed object and an object of type "dynamic", then both should be invalidated at the same time)

Pros and cons (at the same time):

  • designed for generic usage (not with Kentico Cloud data in mind)

Updating Boilerplate found a new issue, possibly?

In an early release of the boilerplate I could use the CachedDeliveryClient's GetItemAsync method without any parameters:

var response = await DeliverClient.GetItemAsync<FullWidthContentPage>(PageCodeName);

I updated to the latest release code as of yesterday, and now I receive an error on that line: "parameter cannot be null". To get around it I was able to pass in an empty List but that was the only way I could get it to work. Like so:

var response = await DeliverClient.GetItemAsync<FullWidthContentPage>(PageCodeName, new List<IQueryParameter>());

I believe the issue is in how the code is written in KenticoCloudCacheHelper.cs for the GetIdentifiersFromParameters method, but I am not 100%.

I'm hoping someone can validate my findings, or tell me if I am wrong?

Caching with Kentico Cloud

Simple fixed-time caching - Could you please provide more details about this functionality?
How it works, when people should use it/should not, what's the best practice for caching in general.

Simple caching

Boilerplate support for .NET Core 3.0

The current Kentico Kontent .NET Core boilerplate only supports .NET Core 2.1. Some of our systems may have limitations for versions of .NET Core under version 3.0 (.NET Core 3.0 added some connectivity functionality for a legacy database system that we use), so an upgrade to .NET Core 3.0 would make using Kentico Kontent simpler in our case. Plus it would keep it in line with our current development plans to implement .NET Core 3.0.

Publish the cache and delivery code as a NuGet package

The current boilerplate project is used to start a new web site on Kentico (users are instructed to do so). As such, users get the than-current code at the time of creating a new web site project. All fixes and improvements you made after that moment are usually missed and they never reach production for already existing web sites.

The boilerplate project contains two parts with different usage scenarios:

  • Code encapsulating the official Kentico library and providing additional library-like features (caching, cache reset webhook, signature check etc.). This part tends to be kept intact in the result web site project.
  • Sample website which shows how to get and show data retrieved from Kentico. This part tends to be heavily replaced in the result web site project.

I would like to see the encapsulating code to be published as a somehow-officially-supported NuGet package.

It will have several benefits:

  • It makes sense. Currently, the boilerplate code mixes two different things with two different usage scenarios (encapsulating library vs. example).
  • Users will get the fixes you make even for existing web site projects.
  • Users will save time not being needed to manually transfer the changes you made in the meantime into their copy of the same code.

It will also have few expectations:

  • Users will expect that you will maintain the library part of the code, upgrade it to support new .NET versions in a timely manner (I mean somewhere between RC and RTM) etc.

I did the split for my private projects as it makes no sense to maintain the same library code in several projects so it is feasible.

Update the template to ASP.NET Core 2.1

Best practice for environment setup

Regarding - Configs for Dev and Production environment
What's the recommended approach to setup environment for development, etc. It would be great to know more details about that, what's the best practice and how boilerplate could help in this manner.

Spike: Pick the best generic cache library

Expected outcome

As it makes sense to support distributed caching along with the existing support of in-memory caching, we'd like to select the most suitable 3rd party caching library to do the job.

Ideally, the library should:

  • be able to handle both distributed and in-mem caching
  • support strongly-typed cache entries
  • be able to set dependencies among cache entries
  • allow the developer to set cache eviction rules (policies) in case of memory pressure

Reference

Note: Rewritten from #52 .

Missing robots.txt

Motivation

Readme.md says it includes a robots.txt, but it does not.

Proposed solution

Add the robots.txt

Additional context

Improve readme

  • setting up caching #26

  • domain redirect #27

  • robots

  • sitemap

  • link resolver #25

  • by @matodanko from #28 :
    Regarding - Configs for Dev and Production environment
    What's the recommended approach to setup environment for development, etc. It would be great to know more details about that, what's the best practice and how boilerplate could help in this manner.

Article's <img> tag is generated with </img> closing even it is a void element

The HtmlHelperExtensions.AssetImage method builds an img tag which than renders as

<img โ€ฆ></img>

The img tag is a void element. So it should be rendered as just <img> (HTML5, HTML) or self-closed <img/> (HTML5, XHTML).

I suggest to add one of the following lines just before the return image; statement to fix this.

image.TagRenderMode = TagRenderMode.SelfClosing; // XHTML-like <img/>

image.TagRenderMode = TagRenderMode.StartTag; // HTML-like <img>

Support VSIX Templates

Make it work with "dotnet new"

AbstractResponse.HasStaleContent is always false

Trying to get the caching to work so that when an item is Published or Unpublished, the cache is cleared straight away on the Live site.

I have noticed within the InvalidatingCacheManager.cs object, there is an if condition checking if the value object is an AbstractResponse object and that the value has the 'HasStaleContent' property set to true (line 54 - attached screenshot below). But, when debugging this functionality, the 'HasStaleContent' value is also returning false.

I was expected this value to be true when an item has been Published or Unpublished.

Screenshots

image

LinkedItems returned as null.

I have recently upgraded a site to the latest version on this boilerplate. After the initial build of the site I noticed that most of the pages are missing sections. This is because the response from the API calls, return any linked item objects as null. When debugging I can see that the correct values are in the JSON response.

I am using the following to get the Project Individual Article:
image

The following is what is returned for the ContentModules object (The correct amount of items but all null). This should be a collection of type object as different content types can be used in this section:
image

This functionality was working fine before I upgraded tho the latest version on the boilerplate but can't see why this wouldn't work now. Has there been any changes been made that would stop this from working, that I have missed?

Any help would be much appreciated.

Update Boilerplate to use v8 of SDK

Motivation

KenticoCloud Delivery SDK has significant breaking changes in version 8, so code based on this boiler plate cannot be updated to version 8, needing it to stay with version 6.

Add code-generation as a pre-build event

Motivation

Let's help developers keep their models in-sync with Kentico Kontent content models.

Design guidelines

Run the code generator as a pre-build event target.

PoC: https://github.com/Kentico/kontent-boilerplate-net/blob/master/src/content/Kentico.Kontent.Boilerplate/Tools/GenerateModels.ps1

Live site not updated after new item's version is published

Brief bug description

Publishing a new version of an item and a corresponding webhook is being received with status code 200. This however leaves the live site still showing the old version of that item.
It seems to be a cache issue as it doesn't get updated with the webhook.

Repro steps

  1. Go to '...'
  2. Click on '....'
  3. Scroll down to '....'
  4. See error

Expected behavior

The cache would get updated and the live site would show the new version of the item.

Test environment

  • Platform/OS: [e.g. .NET Core 2.1, iOS]
  • Browser [e.g. chrome, safari]
  • Version [e.g. 22]

Additional context

Add any other context about the problem here.

Screenshots

Add links to screenshots, if possible.

Make the template parametrizable

Motivation

The dotnet new templates can be made parametrizable. Supplying a parameter value saves manual work needed when the template has been instantiated.

We can think of at least these two potential parameters:

If we eventually add code with integrations into this boilerplate and if we split the boilerplate into smaller projects with their NuGet packages, we might also allow the developer to list parts that they want to be in the form of a NuGet package (instead of raw code) right from the start (when starting a new project). One such integration would be the Personalization SDK.

Reference

Migrate to ASP.NET Core 2.0

  • compare with the standard ASP.NET Core 2.0 template to see if there are any new patterns that we should embrace
  • migrate the code

Add Kentico Cloud Personalization SDK

Motivation

KC has content personalization capabilities. By either placing a predefined JS code into web pages or by using the Tracking API (where JS cannot be used, e.g. native apps), one can start gathering information about visitors, converting them into contacts (after an email address was submitted via any form) and adding them to visitor segments (based on custom rules). Then, a web app may decide which content to render, based on a segment of a particular visitor. The only things needed are adding the JS code, adding the Personalization SDK NuGet package and having some decision logic that operates on the segment information.

Design guidelines

  • Let's add the personalization SDK to the template.
  • Ideally, make it optional (through a dotnet new parameter).

Reference

SignatureActionFilter throwing "System.NotSupportedException"

Brief bug description

With an ngrok url setup and the webhook url set to "webhooks/webhooks/index," I put a breakpoint on the Webhooks controller to follow the code - when it arrives at the "request.Body.Position=0" at line 26, it throws a "System.NotSupportedException" - the alternate Seek() method threw the same exception. When I commented out line 26, the system told me to change ReadToEnd() to async methods, but I ran into the same issues there. Kentico support suggested I open an issue for this.

What went wrong?
Webhook crashes on receiving a new message

Repro steps

Step through code in SignatureActionFilter, starting with line 26

  • Platform/OS: .NET Core 3.0, Windows
  • Browser Chrome and Firefox

Add links to screenshots, if possible.
Error

Add support for content type snippets

Kentico Cloud now supports so called content type snippets. These are sets of content elements that can be added to content types to enrich their structure.

They allow you to add several content elements that are managed in one single place, similarly to how inheritance in object oriented programming works. You can add one snippet to a content type. Snippets cannot be added to other snippets, only to content types. The Delivery API responses contain both the elements originating from snippets alongside their own elements. The only difference in them is that elements from snippets have code names prefixed with the code name of the respective snippet. The format of code names is [code name of snippet]__[code name of element].

A shortened example of a content item:

{
    "item": {
        "system": {
            // ...
            "type": "brewer",
	// ...
        },
        "elements": {
	// ...
            "product_name": {
                "type": "text",
                "name": "Product name",
                "value": "AeroPress"
            },
	// ...
            "metadata__meta_title": {
                "type": "text",
                "name": "Meta title",
                "value": null
            },
	// ...
        }
    },
    "modular_content": {}
}

Implement support for rendering content items of content types that utilize a content snippet.

A temporary Dancing Goat project with a preview of snippets is available for everyone who wants to participate in this effort. If you're interested in either adjusting the sample content or implementing the support in the app, let @JanLenoch know and you'll be given access to that project in Kentico Cloud.

The implementation should be in line with how the code generatorworks.

Currently, this issue is blocked by kontent-ai/model-generator-net#43 . But, the models of this app could be modified manually to overcome the block.

Webhook controller doesn't handle workflow related events

Brief bug description

Workflow related events cannot be deserialized into WebhookModel making the webhook controller action Index not executed since the model is null

Repro steps

Cause the following event to be sent to the webhook:

{
  "data": {
    "items": [
      {
        "item": {
          "id": "76e78624-c7d7-53ae-ab0f-64dfde05e65e"
        },
        "language": {
          "id": "00000000-0000-0000-0000-000000000000"
        },
        "transition_from": {
          "id": "0041a1b3-1820-44d6-bd8a-f252f8f8bf6a"
        },
        "transition_to": {
          "id": "61f60ea5-66e6-4b1e-9c8e-c34e0782f90f"
        }
      }
    ]
  },
  "message": {
    "id": "960a79fc-95b3-42c0-96e3-1493bf6c0193",
    "project_id": "ad8d8eda-c21e-000c-a5e6-7478633c60f3",
    "type": "content_item_variant",
    "operation": "change_workflow_step",
    "api_name": "content_management",
    "created_timestamp": "2019-12-21T00:35:36.2477126Z",
    "webhook_url": "http://2a5a4d10.ngrok.io/webHooks/KenticoKontentWebHook"
  }
}

Expected behavior

There should be support for both type of events either by handling it in different actions or by some other means so both event model to be deserialized by the same action.

Test environment

  • Platform/OS: .NET Core 3.1
  • Boilerplate Version [e.g. 4.0.2]
  • SDK version: 12.3.0

Add full support for IISUrlRewrite.xml file format

So far it's not fully implemented in asp.net core 1.1, but it's implemented in asp.net core 1.2 that should be released in Q2/2017 (source). Once released, we should update boilerplate and add support for fully implemented support for IISUrlRewrite.xml file format.

It will allow our users to use rewrite maps (i.g.: static redirects - old url -> new url).

<rewrite>
  <rewriteMaps>
    <!-- TODO: not supported yet, waiting for asp.net core 1.2 release -->
    <!-- Example of 301 - Permanent redirect with old -> new URL mapping -->
    <rewriteMap name="Static rewrites" defaultValue="">
      <add key="/old-url" value="/?new-url=1" />
    </rewriteMap>
  </rewriteMaps>
</rewrite>

Currently, they have to use workaround or own solution.

Receiving the wrong object from API when getting item by codename.

Description

I have two objects 'Object1' and 'Object2'. 'Object2' is a child of 'Object1' (according to the CMS structure) and I have created a custom method that gets the correct URL path of the current page by it's codename - i.e. "/{object1Url}/{currentPageUrl}" or "/{object1Url}/{object2Url}/{currentPageUrl}".

I first check to see if the current page is of type 'Object1' by using the following request:

IDeliveryItemResponse<Object1> object1Response = _deliveryClient.GetItemAsync<Object1>(codename, new EqualsFilter("system.type", Object1.Codename), new ElementsParameter(Object1.Field1Codename, Object1.Field2Codename)).Result;

If this object is null, I know that the current page is a child of 'Object1'. So, I then check for 'Object2' by the codename, using the following:

IDeliveryItemResponse<Object2> object2Response = _deliveryClient.GetItemAsync<Object2>(codename, new EqualsFilter("system.type", Object2.Codename), new ElementsParameter(Object2.Field1Codename, Object2.Field2Codename)).Result;

I am then calling this custom method in two separate places and get two different results for the same codename (Content Item). In one of the place I am getting the correct result. But, in the second place, I am getting the Content Item of type 'Object2' returned in the 'object1Response' object, where I check to see if it is of type 'Object1'. So, the URL I build is incorrect for the type of page it is.

This only seems to happen when the current page is a child of the 'Object2' section - i.e. "/{object1Url}/{object2Url}/{currentPageUrl}". The codename I'm passing into the method is definitely for a Content Item of type 'Object2' - I have check this a couple time and also had a colleague double check.

Has anyone come across this as well and have any ways around it?

Enhance readme

Adjust the part for generating models:

  • the boilerplate expects <websitename>.Models, while the utility generates KenticoCloudModels by default

404 on webhook endpoint

Brief bug description

According to the webhook debug, new requests sometimes end up with a 404 error. The webhook endpoint is configured on ~/webhooks/webhooks. The 404 status sometimes switches to 200 after some time for already performed webhooks

Repro steps of customer

  1. Setup webhook according to https://github.com/Kentico/kontent-boilerplate-net#how-to-set-up-webhook-enabled-caching
  2. Publish items
  3. Watch status codes in Webhook debug in Kontent UI

Expected behavior

All requests return 200 unless the server is unavailable. Never get 404.

Test environment

  • Platform/OS: .NET Core 3.1
  • Latest Boilerplate version (v4.0.2)

Additional context

The Event log of the webhook endpoint show following stack trace:

System.InvalidOperationException: Unable to resolve service for type 'NoahMedia.Caching.Webhooks.ICacheManager' while attempting to activate 'NoahMedia.Areas.WebHooks.Controllers.WebhooksController'.
at Microsoft.Extensions.DependencyInjection.ActivatorUtilities.GetService(IServiceProvider sp, Type type, Type requiredBy, Boolean isDefaultParameterRequired)
at lambda_method(Closure , IServiceProvider , Object[] )
at Microsoft.AspNetCore.Mvc.Controllers.ControllerActivatorProvider.<>c__DisplayClass4_0.<CreateActivator>b__0(ControllerContext controllerContext)
at Microsoft.AspNetCore.Mvc.Controllers.ControllerFactoryProvider.<>c__DisplayClass5_0.<CreateControllerFactory>g__CreateController|0(ControllerContext controllerContext)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeInnerFilterAsync()
--- End of stack trace from previous location where exception was thrown ---
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResourceFilter>g__Awaited|24_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeFilterPipelineAsync()
--- End of stack trace from previous location where exception was thrown ---
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Logged|17_1(ResourceInvoker invoker)
at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
at NoahMedia.Middleware.SignatureMiddleware.InvokeAsync(HttpContext httpContext, IOptions`1 projectOptions) in C:\Development\Noah\noah-media-group-kentico-cloud-main-website\Middleware\SignatureMiddleware.cs:line 39
at Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware.<Invoke>g__Awaited|6_0(ExceptionHandlerMiddleware middleware, HttpContext context, Task task

Conversation

All details and maybe other beneficial info can be found in conversation 26023165963 and 26078540426.

Rewrite CachedDeliveryClient so that it follows the decorator pattern

Motivation

Currently, the CachedDeliveryClient references protected DeliveryClient DeliveryClient { get; } which is wrong. It should reference IDeliveryClient.

Design guidelines

  • CachedDeliveryClient should accept IDeliveryClient in the constructor
  • The current constructor should be removed/altered
  • Instances of DeliveryClient should be created outside the CachedDeliveryClient
  • public HttpClient HttpClient will no longer be necessary in the CachedDeliveryClient
    • tests will create fake HttpClient and pass it to an instance of the DeliveryClient which will be passed to CachedDeliveryClient

Reference

Why was the webhook signature action filter rewritten into middleware?

Motivation

Middleware was designed by MS to run for all requests, without the notion of routing or other context of MVC.

Conversely, action filters are designed to run for specific controllers/actions.

Given that the webhook secret will never be used throughout the whole app, the rewrite of the SignatureActionFilter class into a middleware makes no sense. The conversion causes that on each and every hit to all controller actions, the request stream is being read and the hash is being calculated, over and over without a use.

Proposed solution

Revert back to an action filter.

Additional context

Blocks #93

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.