【问题标题】:Using Multple Asyncronous Xmlhttprequests to Create/Update Microsoft Dynamics CRM Order Detail Records Not Working使用多个同步 Xmlhttprequests 创建/更新 Microsoft Dynamics CRM 订单详细信息记录不起作用
【发布时间】:2015-07-09 01:23:42
【问题描述】:

我正在尝试使用 oData 端点发送多个异步 xmlhttprequest。其中一些正在创建订单详细信息并正在更新 Microsoft Dynamics CRM 2013 中的订单详细信息。

如果我使用开发人员工具并手动跟踪代码,它可以正常工作。但是,如果我从我的网络资源运行它,我会不断地从服务器收到 500 个响应。一些请求正确完成,而其他请求失败。

我正在寻找一个纯粹的 javascript 解决方案。我试过用谷歌搜索它并查看 stackoverflow 上的多个帖子,但无济于事。我使用了 Fiddler2,但响应文本是“通用 SQL 错误”。如果我在作曲家中再次运行请求,它就可以正常工作。会不会是数据库锁定问题?

提前致谢,如果需要,我可以提供更多信息。

这是我的 for 循环代码:

var updateDetails = function (data) {
    var table = document.getElementById("selectedItemTable");
    var tbody = table.getElementsByTagName("tbody")[0];
    var upsaleQty, qty;
    var salesOrderDetailId;

    for (var i = 0; i < tbody.childElementCount; i++) {
        var prodName = tbody.rows[i].cells[0].innerHTML;
        var match = false;

        for (var j = 0; j < data.length; j++) {
            if (prodName === data[j].product_order_details.tf_ShortName) {
                match = true;
                upsaleQty = data[j].tf_UpsaleQty ? parseFloat(data[j].tf_UpsaleQty) : 0;
                qty = parseFloat(data[j].Quantity) + parseFloat(tbody.rows[i].cells[1].innerHTML);
                salesOrderDetailId = data[j].SalesOrderDetailId;
            }
        }

        if (!match) {
            var productQuery = odataBaseUrl + "/ProductSet?$filter=tf_ShortName eq '" + prodName + "'&$select=Name,tf_ShortName,ProductId,DefaultUoMId";
            performRequest(productQuery, createDetail);
        } else {
            upsaleQty = upsaleQty + parseFloat(tbody.rows[i].cells[1].innerHTML);

            // Update Order Detail
            var updateObj = {};
            updateObj.tf_UpsaleQty = upsaleQty.toFixed(5);
            updateObj.Quantity = qty.toFixed(5);

            var updateDetail = JSON.stringify(updateObj);

            console.dir("Update " + prodName + ":" + updateDetail);

            createUpdateDetail(true, salesOrderDetailId, updateDetail);
        }
    }

    makePdf();
    document.getElementById("save").style.visibility = "hidden";
}

这是发送创建/更新请求的代码:

var createUpdateDetail = function (update, orderDetailGuid, json) {
    var odataReq = odataBaseUrl + "/SalesOrderDetailSet";

    if (update) {
        odataReq += "(guid'" + orderDetailGuid + "')";
    }

    var oReq = getXMLHttpRequest();

    if (oReq != null) {
        oReq.open("POST", encodeURI(odataReq), true);
        oReq.setRequestHeader("Accept", "application/json");
        oReq.setRequestHeader("Content-Type", "application/json; charset=utf-8");

        if (update) {
            oReq.setRequestHeader("X-HTTP-Method", "MERGE");
        }

        oReq.send(json);
    } else {
        alert('Error in creating request.');
    }
}

这里是执行请求函数:

var performRequest = function (odataUrl, onReadyFunction, concatResults) {
    console.dir(odataUrl);

    var oReq = getXMLHttpRequest();
    if (oReq != null) {
        oReq.open("GET", encodeURI(odataUrl), true);
        oReq.setRequestHeader("Accept", "application/json");
        oReq.setRequestHeader("Content-Type", "application/json; charset=utf-8");
        oReq.onreadystatechange = function () {
            if (oReq.readyState == 4 && oReq.status == 200) {
                // Parse the result

                if (!concatResults) {
                    concatResults = new Object();
                    concatResults.results = new Array();
                }

                oReq.onreadystatechange = null; //avoids memory leaks
                console.dir(oReq.responseText);
                var result = window.JSON.parse(oReq.responseText).d;

                for (var i = 0; i < result.results.length; i++) {
                    concatResults.results.push(result.results[i])
                }

                if (result.__next != null)
                    performRequest(decodeURI(result.__next), onReadyFunction, concatResults);
                else
                    onReadyFunction(concatResults.results);
            }
        };
        oReq.send();
    } else {
        alert('Error in creating request.');
    }

}

创建细节函数:

var createDetail = function (data) {
    // Create Order Detail
    var table = document.getElementById("selectedItemTable");
    var tbody = table.getElementsByTagName("tbody")[0];
    var qty = 0;

    for (var i = 0; i < tbody.childElementCount; i++) {
        if (data[0].tf_ShortName === tbody.rows[i].cells[0].innerHTML) {
            qty = parseFloat(tbody.rows[i].cells[1].innerHTML).toFixed(5);
        }
    }

    var createObj = {};
    createObj.SalesOrderId = { Id: orderGuid, LogicalName: "salesorder" };
    createObj.ProductId = { Id: data[0].ProductId, LogicalName: "product" };
    createObj.Quantity = qty;
    createObj.tf_UpsaleQty = qty;
    createObj.UoMId = { Id: data[0].DefaultUoMId.Id, LogicalName: data[0].DefaultUoMId.LogicalName };
    var createDet = JSON.stringify(createObj);

    console.dir("Create:" + createDet);

    createUpdateDetail(false, "", createDet);
}

【问题讨论】:

    标签: javascript asynchronous xmlhttprequest dynamics-crm


    【解决方案1】:

    我认为 ExecuteMultipleRequest 到 SOAP 端点是您的解决方案。因此,您只会获得一个服务调用,而不是进行当前在您的解决方案中实现的多个服务调用。

    如果您避免在代码中生成到soap端点的请求字符串,我想向您推荐this JS库。

    【讨论】:

    • 你有一个例子,我可以看看 ExcuteMultipleRequest to SOAP 在 javascript 中是如何工作的?
    • 如果您决定使用 COSA Js 库,您可以在文档部分找到示例代码。点击链接
    【解决方案2】:

    我最终创建了一个数组并将其视为队列。我将所有用于创建和更新订单详细信息的 odata 请求放入数组中,然后按顺序处理它们。 onreadystatechange 将触发下一个请求。当然,它不如并行运行处理的效率高,但它满足了我的需求并解决了 500 个错误。感谢您的帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-05-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多