WFFM переопределяет идентификатор формы, выбранный в деталях презентации

В определенном сценарии мне нужно программно изменить форму WFFM, представленную в средстве визуализации форм. Сам модуль визуализации формы добавляется к заполнителю через сведения о презентации.

Я могу получить доступ к рендеру формы и установить FormID и обновить его параметры до идентификатора формы, которую я хочу отобразить вместо этого. Однако создается впечатление, что Sitecore не учитывает эти свойства и не отображает исходную форму, даже когда я перемещаю свой код ранее в жизненном цикле страницы, например. Страница_Инит. Мой код выглядит следующим образом

    // Pass in controls of the sublayout
    public FormRender SetFormRender(Control control, string dataSource)
    {
        FormRender formRender = null;

        // loop through controls contained in passed in control
        foreach (Control child in control.Controls)
        {
            if (child is FormRender)
            {
                formRender = child as FormRender;
                if (formRender != null)
                {
                    formRender.FormID = dataSource;
                    formRender.Parameters = "FormID=" + HttpUtility.HtmlEncode(dataSource);
                    break;
                }
            }

            // If control has controls pass to this method for recursion 
            if (control.HasControls())
            {
                var nestedFormRender = SetFormRender(child, dataSource);
                if (nestedFormRender != null && formRender == null)
                {
                    formRender = nestedFormRender;
                    break;
                }

            }
        }

        return formRender;
    }

person Jonathan Robbins    schedule 18.06.2015    source источник
comment
Вы пытались установить formRender.DataSource = datasource? В более новых версиях WFFM произошли изменения, поэтому используются значения источника данных, по крайней мере, для MVC, и они выглядят одинаково для WebForms. FormRender.FormID также сначала проверяет значение источника данных, а в противном случае использует FormID, установленный в GetRender(), что может быть слишком поздно, поскольку элемент управления уже инициализирован.   -  person jammykam    schedule 19.06.2015


Ответы (3)


Возможно, после того, как вы установите FormID и Parameter, вам нужно будет вызвать FormRender.OnInit(), поэтому ваш код может выглядеть так:

....
formRender.FormID = dataSource;
formRender.Parameters = "FormID=" + HttpUtility.HtmlEncode(dataSource);
formRender.OnInit(null);                   
break;
....

Изменить

Я не думаю, что вы можете вызвать formRender.OnInit() из своего кода в качестве его защищенного метода, но вы можете создать новый элемент управления, который наследует FormRender, и заменить элемент в деталях презентации этим, а затем переопределить OnInit() метод и поместите свой код, который обрабатывает свойство FormID, затем вызовите base.OnInit()

Майк Рейнольдс ведет блог о том, как загружать различные формы на основе строки запроса здесь

person Ahmed Okour    schedule 19.06.2015
comment
Вы правы в том, что OnInit() является защищенным методом. Я думаю, что следующим подходом будет создание элемента управления, реализующего FormRender. Я тоже почитаю блог Майка. - person Jonathan Robbins; 22.06.2015
comment
Ваше редактирование помогло мне найти решение - спасибо за помощь - person Jonathan Robbins; 23.06.2015

Я нашел решение на основе блог Майка Рейнольдса, как предложил Ахмед Окур, помог мне достичь 50% результата, но потребовал дополнительной работы.

Я создал новый FormRender, который предоставил общедоступное свойство для передачи переопределяющего идентификатора формы. Этот новый FormRender реализует существующий, однако переопределение базового OnInit() по-прежнему создает защищенный метод, что означает, что его нельзя вызвать, когда он нам нужен. Поэтому я создал открытый метод OnInit() без переопределения:

public class PublicFormRender : FormRender
{
    public string OverridingFormId { get; set; }

    public void OnInit()
    {
        OnInit(new EventArgs());
    }

    protected override void OnInit(System.EventArgs e)
    {
        // New logic added here so overriding Id is always honoured
        // especially in the case of PublicFormRender is added via the FrontEnd
        if (!string.IsNullOrEmpty(OverridingFormId))
        {
            FormID = OverridingFormId;
            var parameters = WebUtil.ParseUrlParameters(Parameters);
            if (parameters["FormID"] != null)
                parameters["FormID"] = HttpUtility.HtmlEncode(OverridingFormId);
            Parameters = parameters.ToString();
        }

        base.OnInit(e);
    }
}

Я продублировал FormRender в Sitecore по пути /sitecore/layout/Renderings/Modules/Web Forms for Marketers/, ссылаясь на PublicFormRender, и использовал его для добавления форм в сведениях о презентации.

    public PublicIdFormRender SetFormRender(Control control, string dataSource)
    {
        PublicIdFormRender formRender = null;

        // Loop through to find the new PublicFormRender
        foreach (Control child in control.Controls)
        {
            var publicFormRender = child as PublicFormRender;
            if (publicFormRender != null)
            {
                // Set the new public property to the data source
                publicFormRender.OverridingFormId = dataSource;
                // Initialise the Form via the non-overriding public method
                publicFormRender.OnInit();
                formRender = publicFormRender;
                break;
            }

            if (control.HasControls())
            {
                var nestedFormRender = SetFormRender(child, dataSource);
                if (nestedFormRender != null && formRender == null)
                {
                    formRender = nestedFormRender;
                    break;
                }

            }
        }

        return formRender;
    }
person Jonathan Robbins    schedule 23.06.2015

Это связано с тем, что форма фактически отображается при добавлении в коллекцию элементов управления. Если вы должны придерживаться этой архитектуры, я предлагаю удалить элемент управления из коллекции, а затем добавить его через

control.Controls.Add(formRender);

Не очень эффективно, но должно работать.

person Amir Setoudeh    schedule 19.06.2015