Как в EPiServer Xforms реализована единичная отправка? - PullRequest
0 голосов
/ 30 ноября 2011

Как Один и тот же человек может отправить форму несколько раз реализована функциональность? Если это поле в редакторе XForm не отмечено, пользователь может отправить форму только один раз.

Я думал, что для анонимных пользователей это был файл cookie, но я не вижу соответствующих файлов cookie, передаваемых по проводам. Глядя на EPiServer.XForms.XFormData.HasAlreadyPosted(Page page) в ILSpy, вы увидите, что он на самом деле проверяет cookie, если для параметров персистентности не задано значение Database или имя пользователя равно NULL.

В этой ситуации он проверяет наличие cookie с именем «FormCookie»:

private static bool CheckCookieForPostedForm(Guid formId, Page page)
{
    HttpCookie httpCookie = page.Request.Cookies["FormCookie"];
    if (httpCookie != null)
    {
        foreach (string text in httpCookie.Values.Keys)
        {
            if (text.Equals(formId.ToString()))
            {
                return true;
            }
        }
        return false;
    }
    return false;
}

Я тестирую как анонимный пользователь, но в запросе или ответе на запрос POST формы или запросе или ответе на странице благодарности отсутствует «FormCookie», поэтому я не вижу, как это работает .

Следуя логике для анонимных пользователей, если вы отправляете сообщение в базу данных, а имя пользователя не равно NULL, существует запрос Linq, который проверяет DDS на отправку с совпадающими FormId и UserName.

public bool HasAlreadyPosted(Page page)
{
    if ((this.ChannelOptions & ChannelOptions.Database) != ChannelOptions.Database  
        || this.UserName == null)
    {
        return XFormData.CheckCookieForPostedForm(this.FormId, page);
    }

    if (Guid.Empty.Equals(this.FormId))
    {
        throw new InvalidOperationException(  
          "Cannot read the XFormData before the FormName property has been set");
    }

    DynamicDataStore store = XFormData.GetStore(this.FormId);
    int num = (from post in store.ItemsAsPropertyBag()
               where (Guid)post["Meta_FormId"] == this.FormId &&  
                     (string)post["Meta_UserName"] == this.UserName
               select post).Count<PropertyBag>();
    return num > 0;
}

При просмотре в базе данных (tblXFormData) в столбце UserName нет значений NULL. Может случиться так, что вышеприведенная проверка this.UserName == null не удалась, тогда она выполняет запрос Linq, который сравнивает имя пользователя анонимного пользователя с именами в таблице, из которых пустой от первого анонимного пользователя, и сообщает о ложном положительный?

1 Ответ

1 голос
/ 29 мая 2012

То, что я смог сделать, - это использовать метод OnInit, используя событие AfterSubmitPostedData, чтобы затем использовать метод SetPostedCookie в обработчике. Затем создается файл cookie FormCookie, как описано в вашем сообщении.

Документация API не самая лучшая.

public void FormControl_AfterSubmitPostedData(object sender, SaveFormDataEventArgs e)
{
    this.ShowStats();

    // we do this in the case of an anonymous user votes on the site.
    XFormData xfd = this.FormControl.FormDefinition.CreateFormData();
    xfd.SetPostedCookie(xfd.FormId, Page);
}
...