EPiServer Xforms 中如何实现单次提交?

发布于 2024-12-18 21:35:56 字数 1885 浏览 3 评论 0原文

同一个人可以多次发送表单功能是如何实现的?当 XForm 编辑器中的该字段未选中时,用户只能提交表单一次。

我认为对于匿名用户来说,它是基于 cookie 的,但我看不到任何相关的 cookie 通过网络传输。查看 ILSpy 中的 EPiServer.XForms.XFormData.HasAlreadyPosted(Page page) 表明,如果持久性选项未设置为 Database 或 UserName 为 null,它实际上会检查 cookie。

在这种情况下,它会检查名为“FormCookie”的 cookie:

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”所以我看不出这是如何运作的。

按照匿名用户的逻辑,如果您要发布到数据库并且 UserName 不为 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 查询,该查询将匿名用户的用户名与表中的用户名进行比较,其中有一个空来自第一个匿名用户并报告误报?

How is the Same person can send the form several times functionality implemented? When this field in the XForm editor is unchecked, the user can only submit the form once.

I thought for anonymous users it was based on a cookie but I can't see any relevant cookies going over the wire. Looking at EPiServer.XForms.XFormData.HasAlreadyPosted(Page page) in ILSpy shows that it does in fact check a cookie if the persistance options isn't set to Database or the UserName is null.

In this situation it checks for a cookie named "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;
}

I'm testing as an anonymous user but there is no "FormCookie" present in the request or response on the POST of the form or the request or response on the Thank You page so I can't see how this is working.

Following the logic for anonymous users, if you're posting to the database and the UserName is not null, there is a Linq query which checks the DDS for a submission with a matching FormId and 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;
}

Looking in the database (tblXFormData), there are no NULL values in the UserName column. Could it be that the this.UserName == null check above is failing, then it's executing the Linq query which comparing the username of an anonymous user to the usernames in the table, of which there is an empty one from the first anonymous user and reporting a false positive?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

红衣飘飘貌似仙 2024-12-25 21:35:56

我能够做的是在 OnInit 方法中使用 AfterSubmitPostedData 事件,然后在处理程序中使用 SetPostedCookie 方法。然后,这将创建 FormCookie cookie,如您的帖子中所述。

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);
}

What I was able to do was in the OnInit method use the AfterSubmitPostedData event to then use the method SetPostedCookie in the handler. This then creates the FormCookie cookie as described in your post.

The api documentation isn't the best.

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);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文