Внедрение динамического контента в тело страницы Orchard

Можно ли вставлять динамический контент в тело страницы Orchard? Я хотел бы ввести идентификатор текущего вошедшего в систему пользователя в ссылки.

Моя первоначальная мысль состояла в том, чтобы использовать замену токена, поэтому ввод <a href="http://www.someurl.com?id=[memberid]"></a> заменял бы [memberid] идентификатором вошедшего в систему пользователя во время выполнения. Есть ли способ перехватить ответ и запустить некоторый пользовательский код, прежде чем он будет отправлен обратно клиенту?

Это тот же вопрос, однако ответ очень специфичен для их проблемы.


person David Williams    schedule 19.09.2014    source источник


Ответы (1)


Токены могут быть правильным способом, однако я еще не вникал в это. Но если вы хотите изменить ответ, вы можете использовать фильтры ответов.

Я использовал его для минимизации результирующего HTML-кода в этом модуле https://gallery.orchardproject.net/List/Modules/Orchard.Module.JadeX.HtmlMarkupMinifier

Вот код, который должен помочь или, по крайней мере, дать вам представление.

using System.Globalization;
using System.IO;
using System.Text;
using System.Web.Mvc;
using Orchard;
using Orchard.Mvc.Filters;
using Orchard.UI.Admin;

public class TokenReplacementFilter : FilterProvider, IActionFilter
{
    private readonly WorkContext _workContext;

    public TokenReplacementFilter(IWorkContextAccessor workContextAccessor)
    {
        _workContext = workContextAccessor.GetContext();
    }

    public void OnActionExecuting(ActionExecutingContext filterContext) {
        // Only apply the token replacement if logged in and not in the Orchard admin area
        if (filterContext.HttpContext.Response.Filter == null || _workContext.CurrentUser == null || AdminFilter.IsApplied(filterContext.RequestContext))
            return;

        filterContext.HttpContext.Response.Filter = new TokenReplacementStream(filterContext.HttpContext.Response.Filter, filterContext.HttpContext.Response.Output.Encoding, _workContext);
    }

    public void OnActionExecuted(ActionExecutedContext filterContext)
    {
    }
}

internal class TokenReplacementStream : MemoryStream
{
    private readonly Stream _stream;
    private readonly Encoding _encoding;
    private string _html;
    private readonly WorkContext _workContext;

    public TokenReplacementStream(Stream filter, Encoding encoding, WorkContext workContext)
    {
        _stream = filter;
        _encoding = encoding;
        _workContext = workContext;
    }

    public override void Write(byte[] buffer, int offset, int count)
    {
        _html += _encoding.GetString(buffer);
    }

    public override void Flush()
    {
        if (_html != null) {
            _html = _html.Replace("[memberid]", _workContext.CurrentUser.Id.ToString(CultureInfo.InvariantCulture));
            _stream.Write(_encoding.GetBytes(_html), 0, _encoding.GetByteCount(_html));   
        }
    }
}
person Xeevis    schedule 19.09.2014
comment
Спасибо за ваш ответ, только что попробовал, но я получаю исключение HttpException с бесполезным сообщением «Фильтрация не разрешена». с кодом ошибки -2147467259. Однако он по-прежнему попадает в код метода Flush в фильтре. - person David Williams; 22.09.2014
comment
Дэн, жаль это слышать. Я добавил одну нулевую проверку в OnActionExecuting, не могли бы вы попробовать с ней? Также, если вы работаете в режиме отладки, попробуйте отключить его, если это поможет. - person Xeevis; 22.09.2014
comment
Нулевая проверка помогла, спасибо. Мне также пришлось не применять фильтр на сайте администратора, так как он заменял мои токены! Произошла ошибка компиляции из-за того, что WorkContext был недоступен в 1 области, я исправил это и внес несколько изменений в имена, чтобы лучше соответствовать моему проекту. Я внес правку, но в ней говорится, что ее необходимо «проверить», и как только это будет сделано, я отмечу этот ответ как принятый. - person David Williams; 23.09.2014
comment
Редактирование было отклонено по какой-то причине, в нем говорится: «Это редактирование неверно или является попыткой ответить или прокомментировать существующее сообщение». Однако я столкнулся с проблемой, это ошибки при выходе из сайта, просто смотрю на это сейчас. - person David Williams; 23.09.2014
comment
Ошибка была связана с каким-то другим кодом и не имела отношения к этому. Я внес несколько улучшений в код, чтобы устранить некоторые ошибки, с которыми я столкнулся, но, как отмечалось выше, он продолжает отклоняться, когда я пытаюсь его отредактировать. Я не хочу публиковать ответ сам и принимать это, поскольку вы заслуживаете похвалы. Я мог бы опубликовать это в ответе, который позволит вам скопировать и вставить его, а затем я могу удалить ответ, что вы думаете? - person David Williams; 23.09.2014
comment
Я опубликовал ответ с кодом и объяснением изменений. Не стесняйтесь взять код, и я приму ваш ответ и удалю свой - person David Williams; 23.09.2014
comment
Сделанный. Я также взял на себя смелость изменить вашу проверку администратора, чтобы она основывалась на фильтре, а не на основе темы, поскольку название темы может измениться в будущем. - person Xeevis; 23.09.2014
comment
Великолепно! Не знал об этом AdminFilter. Большое спасибо за вашу помощь. - person David Williams; 24.09.2014