Пример #1
0
            public void OnException(ExceptionContext filterContext)
            {
                var disabled = _exceptionFilterSettings?.Disabled ?? false;

                if (_publishedModelFactory.IsLiveFactoryEnabled() &&
                    !disabled &&
                    !filterContext.ExceptionHandled &&
                    (filterContext.Exception is ModelBindingException || filterContext.Exception is InvalidCastException) &&
                    IsMessageAboutTheSameModelType(filterContext.Exception.Message))
                {
                    filterContext.HttpContext.Response.Headers.Add(HttpResponseHeader.RetryAfter.ToString(), "1");
                    filterContext.Result = new RedirectResult(filterContext.HttpContext.Request.GetEncodedUrl(), false);

                    filterContext.ExceptionHandled = true;
                }
            }
Пример #2
0
        /// <inheritdoc />
        public void Notify(ContentTypeCacheRefresher.JsonPayload[] payloads)
        {
            EnsureCaches();

            foreach (var payload in payloads)
            {
                _logger.LogDebug("Notified {ChangeTypes} for {ItemType} {ItemId}", payload.ChangeTypes, payload.ItemType, payload.Id);
            }

            Notify <IContentType>(_contentStore, payloads, RefreshContentTypesLocked);
            Notify <IMediaType>(_mediaStore, payloads, RefreshMediaTypesLocked);

            if (_publishedModelFactory.IsLiveFactoryEnabled())
            {
                // In the case of ModelsMode.InMemoryAuto generated models - we actually need to refresh all of the content and the media
                // see https://github.com/umbraco/Umbraco-CMS/issues/5671
                // The underlying issue is that in ModelsMode.InMemoryAuto mode the IAutoPublishedModelFactory will re-compile all of the classes/models
                // into a new DLL for the application which includes both content types and media types.
                // Since the models in the cache are based on these actual classes, all of the objects in the cache need to be updated
                // to use the newest version of the class.

                // NOTE: Ideally this can be run on background threads here which would prevent blocking the UI
                // as is the case when saving a content type. Initially one would think that it won't be any different
                // between running this here or in another background thread immediately after with regards to how the
                // UI will respond because we already know between calling `WithSafeLiveFactoryReset` to reset the generated models
                // and this code here, that many front-end requests could be attempted to be processed. If that is the case, those pages are going to get a
                // model binding error and our ModelBindingExceptionFilter is going to to its magic to reload those pages so the end user is none the wiser.
                // So whether or not this executes 'here' or on a background thread immediately wouldn't seem to make any difference except that we can return
                // execution to the UI sooner.
                // BUT!... there is a difference IIRC. There is still execution logic that continues after this call on this thread with the cache refreshers
                // and those cache refreshers need to have the up-to-date data since other user cache refreshers will be expecting the data to be 'live'. If
                // we ran this on a background thread then those cache refreshers are going to not get 'live' data when they query the content cache which
                // they require.

                using (_contentStore.GetScopedWriteLock(_scopeProvider))
                {
                    NotifyLocked(new[] { new ContentCacheRefresher.JsonPayload(0, null, TreeChangeTypes.RefreshAll) }, out _, out _);
                }

                using (_mediaStore.GetScopedWriteLock(_scopeProvider))
                {
                    NotifyLocked(new[] { new MediaCacheRefresher.JsonPayload(0, null, TreeChangeTypes.RefreshAll) }, out _);
                }
            }

            CurrentPublishedSnapshot?.Resync();
        }