【问题标题】:Saving Sitecore Web form for marketers programmatically以编程方式为营销人员保存 Sitecore Web 表单
【发布时间】:2014-03-04 09:39:45
【问题描述】:

如何在不使用提交按钮的情况下保存表单(我在页面上有另一个触发器可用于运行保存代码)。该表单永远不会显示给用户,我只需要将其保存到营销人员数据库的网络表单中,当然除非有更智能的方法。

我可以很好地使用它

Sitecore.Forms.Core.Data.FormItem form =
 Sitecore.Forms.Core.Data.FormItem.GetForm(formID);

但是,我想

  1. 更改表单字段中的数据

(即类似的东西)

form.Fields["Name"] = "Test name"; 
// this wont work, I dont know how to access the field's value before I store it.
  1. 将表单数据保存在 web 表单中,以供 sitecore 中的营销人员项目数据库使用。

修改完字段后,我当然想保存。

【问题讨论】:

    标签: c# database sitecore web-forms-for-marketers


    【解决方案1】:

    这样做的方法是首先获取表单的副本,使用 AdaptedControlResult 列表设置其字段,然后使用 InsertForm 保存它。这样它就会正确地出现在 WFFM 的数据表中。

    代码中使用的 customerInfo 来自 CartHelper,但它可以是任何东西。

    代码:

    string formID = "{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}";
    DataUri uri = new DataUri(new ID(formID));
    Sitecore.Data.Items.Item formItem = Sitecore.Context.Database.GetItem(uri);
    
    // if the item exists, run through all the known fields and add the values from the customerinfo into them.
    if (formItem != null)
    {
       List<AdaptedControlResult> acrList = new List<AdaptedControlResult>();
       Sitecore.Data.Items.Item[] fieldItems = formItem.Axes.GetDescendants();
    
       foreach (Sitecore.Data.Items.Item fieldItem in fieldItems) //.Where(x => x.TemplateName == "Field"))
       {
          if (fieldItem.Name == "E-mail")
          {
             acrList.Add(new AdaptedControlResult(new ControlResult(fieldItem.Name, System.Web.HttpUtility.UrlDecode(customerInfo.Email), string.Empty) { FieldID = fieldItem.ID.ToString(), FieldName = fieldItem.Name, Value = System.Web.HttpUtility.UrlDecode(customerInfo.Email) }, true));
             continue;
          }
    
       // same for all other fields.
       }
    
       // save data
       if (acrList.Count > 0)
       {
          AdaptedResultList arl = new AdaptedResultList(acrList);
    
          try
          {
             Sitecore.Forms.Data.DataManager.InsertForm(formItem.ID, arl, Sitecore.Data.ID.NewID, null);
          }
          catch (Exception ex)
          {
             // Log data here
          }
       }
    }
    

    【讨论】:

    • 这不再适用于 Sitecore 8.0+。 Sitecore.Forms.Data 不再有名为 InsertForm 的方法。
    【解决方案2】:

    如果您尝试以编程方式将数据提交到数据库中的 WFFM 表,您可以使用以下方法:

    假设您在此类的列表中填充了字段列表:

    public class WffmField
        {
            public string FieldName { get; set; }
            public string FieldGuid { get; set; }
            public string FieldValue { get; set; }
        }
    

    字段 guid 将是来自 sitecore 的 guid:

    然后您可以保存到 WFFM 数据库:

    // This should be populated with the data you want to send to the WFFM database
    var fields = new List<WffmField>(); 
    var wffmDatabaseFields = fields.Select(GetWFFMDatabaseField).ToList();
    
    Sitecore.Forms.Data.DataManager.InsertForm(
        formId: new Sitecore.Data.ID("<Form guid here>"),
        fields: new AdaptedResultList(wffmDatabaseFields),
        sessionID: AnalyticsTracker.SessionId,
        data: null);
    

    希望这会有所帮助!

    【讨论】:

    • 这个答案太老了,它不适用并且已经在其他地方说明过
    • 这不再适用于 Sitecore 8.0+。 Sitecore.Forms.Data 不再有名为 InsertForm 的方法。
    【解决方案3】:

    如果我理解你的问题是正确的;你在这里混淆了两个原则。您想让表单通过它自己的单独提交例程 - 但看起来您正在尝试编写自己的表单提交,使用永远不会以您描述的方式工作的服务器端代码。

    从页面上的另一个控件提交 WFM 的最佳方法是让它在表单上仍然使用“提交”类型的按钮,但使用 CSS 隐藏实际控件。它有一个独特的 css 类,您可以使用它来隐藏它。然后 - 从您想要控制提交的页面的其他区域,触发隐藏控件的 OnClick 事件以获取表单回发并保存内容。

    您的代码;我读它的方式;正在尝试读取 Sitecore 表单项,然后访问该 Sitecore 项的字段集合。此字段集合与您的表单没有直接关系,并且永远不会保存用户在网站上当前输入的实际数据。

    【讨论】:

    • 我让它工作了,但我确实考虑过渲染 HTML,然后隐藏它,因为它有一个只存在于服务器内存中的“虚拟”表单。
    【解决方案4】:

    我最近对这个问题有类似的要求。来自Jesper HoffThe answer above 非常棒,如果您需要做的只是将表单数据保存到为WFfM 配置的数据库中。但是,它没有执行与表单关联的保存操作。因此,如果您想将提交记录到 SQL Server 中是可以的,但如果您需要通过电子邮件发送它们,或者将它们传输到 CRM,这将无济于事。我需要在我正在处理的代码中进行电子邮件发送工作,因此我对 WFfM 的内部进行了更多挖掘:

    如果您希望基于代码的提交遵循为表单配置的保存操作,那么您需要对上面的代码进行三个关键更改:

    • 首先你需要使用Sitecore.Form.Core.Submit.SubmitActionManager.Execute()方法而不是Sitecore.Forms.Data.DataManager.InsertForm()。当您发回有效表单时,这似乎是 WFfM 内部调用的内容。
    • 其次,您需要获取并配置已为您的 WFfM 设置的保存操作集以进行定义。要以正确的格式获取这些数据,还需要进行一些调整。
    • 第三,您需要将表单数据收集为ControlResult 对象而不是AdaptedControlResult。作为对Execute() 的调用的一部分,您传入的数据会自动包装。

    为了清楚起见忽略错误检查,我最终得到了这样的代码:

    List<ControlResult> results = new List<ControlResult>();
    results.Add(makeControlResult(_nameFieldID, "Name", "Bob Jones"));
    results.Add(makeControlResult(_emailFieldID, "Email", "B.Jones@test.com"));
    results.Add(makeControlResult(_messageFieldID, "Message", "Lorem ipsum. Dolor sit amet."));
    
    Item formItem = Sitecore.Context.Database.GetItem(_yourFormID);
    
    SitecoreSimpleForm simpleForm = new SitecoreSimpleForm(formItem);
    var saveActionXml = simpleForm.FormItem.SaveActions;
    var actionList = Sitecore.Form.Core.ContentEditor.Data.ListDefinition.Parse(saveActionXml);
    
    List<ActionDefinition> actionDefinitions = new List<ActionDefinition>();
    actionDefinitions.AddRange(actionList.Groups.SelectMany(x => x.ListItems).Select(li => new ActionDefinition(li.ItemID, li.Parameters) { UniqueKey = li.Unicid }));
    
    Sitecore.Form.Core.Submit.SubmitActionManager.Execute(_formID, results.ToArray(), actionDefinitions.ToArray());
    

    保存操作集及其配置保存在表单的Item 中,但您必须将项目包装在SitecoreSimpleForm 对象中才能将其取出。您返回的是 XML,因此您需要使用 Sitecore.Form.Core.ContentEditor.Data.ListDefinition.Parse() 方法对其进行解析,以便返回一组反序列化的 Save Action 对象。但是,它们不是 SubmitActionManager 的正确对象类型,因此您需要将它们投影到 ActionDefinition 对象中才能使用它们。

    (请注意,解析 XML 后获得的 Save Action 对象不在平面列表中,因此在使用它们之前需要使用 SelectMany() 之类的东西将其展平)

    上面引用的makeControlResult()方法只是为了让sn-p更清晰。它只是根据表单字段的数据创建一个ControlResult 对象:

    public ControlResult makeControlResult(string fieldID, string fieldName, string fieldValue)
    {
        return new ControlResult(fieldName, fieldValue, string.Empty)
        {
            FieldID = fieldID,
            FieldName = fieldName,
            Value = fieldValue, 
            Parameters = string.Empty
        };
    }
    

    根据您获取数据的方式,您可能更愿意使用其他答案中的方法的变体来生成此数据。

    我也是wrote up a bit more detail of how I arrived at this answer on my blog。该帖子还包含一个关于如何恢复保存操作可能生成的任何错误的 sn-p - 这在您使用多个保存操作时可能很重要。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多