SharePoint 框架 httpClient.post 对 _vti_bin/lists.asmx 的响应

SharePoint Framework httpClient.post to _vti_bin/lists.asmx response

我正在尝试将 javascript webpart 重写为 Sharepoint Framework。

在此 Web 部件中,我需要对 /_vti_bin/Lists.asmx 进行 soap post 操作,以便扩展日历列表中的所有事件,并将重复发生的事件放在它。

javascript 代码如下所示

    wsURL = webUrl + "/_vti_bin/Lists.asmx";
    var xmlCall =
        "<soap:Envelope xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/'> <soap:Body>" +
        "<GetListItems xmlns='http://schemas.microsoft.com/sharepoint/soap/'>" +
        "<listName>" + calendarList + "</listName>" +
        "<query>" +
        "<Query>" +
        "<Where>" +
           "<DateRangesOverlap>" +
           "<FieldRef Name=\"EventDate\" />" +
           "<FieldRef Name=\"EndDate\" />" +
           "<FieldRef Name=\"RecurrenceID\" />" +
           "<Value Type='DateTime'><Year/></Value>" +
           "</DateRangesOverlap>" +
        "</Where>" +
        "</Query>" +
        "</query>" +
        "<queryOptions>" +
        "<QueryOptions>" +
            "<ExpandRecurrence>TRUE</ExpandRecurrence>" +
        "</QueryOptions>" +
        "</queryOptions>" +
        "</GetListItems>" +
        "</soap:Body></soap:Envelope>";

    var result = [];
    $.ajax({
        url: wsURL,
        type: "POST",
        dataType: "xml",
        async: false,
        data: xmlCall,
        complete: function (xData, status) {
            if (status === "success") {
                var root = $(xData.responseText);
                root.find("listitems").children().children().each(function () {
                    $this = $(this);
                    var ids = $this.attr("ows_UniqueId").split(";");
                    var rec = $this.attr("ows_fRecurrence");

                        result.push({
                            "StartTime": $this.attr("ows_EventDate"),
                            "EndTime": $this.attr("ows_EndDate"),
                            "Title": $this.attr("ows_Title"),
                            "Recurrence": (rec === "1" ? true : false),
                            "Description": $this.attr("ows_Description"),
                            "Guid": ids[1],
                            "Id": ids[0],
                        });

                });
            }
        },
        contentType: "text/xml; charset=\"utf-8\""
    });
    return result;
};

但现在我正尝试用打字稿重写这段代码,但我似乎无法取回响应文本?

这是我的 TypeScript 函数

private makeRequest(listName: string): Promise<HttpClientResponse> {

let wsURL = this.context.pageContext.web.absoluteUrl + "/_vti_bin/Lists.asmx";
var xmlCall =
    "<soap:Envelope xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/'> <soap:Body>" +
    "<GetListItems xmlns='http://schemas.microsoft.com/sharepoint/soap/'>" +
    "<listName>" + listName + "</listName>" +
    "<query>" +
    "<Query>" +
    "<Where>" +
       "<DateRangesOverlap>" +
       "<FieldRef Name=\"EventDate\" />" +
       "<FieldRef Name=\"EndDate\" />" +
       "<FieldRef Name=\"RecurrenceID\" />" +
       "<Value Type='DateTime'><Year/></Value>" +
       "</DateRangesOverlap>" +
    "</Where>" +
    "</Query>" +
    "</query>" +
    "<queryOptions>" +
    "<QueryOptions>" +
        "<ExpandRecurrence>TRUE</ExpandRecurrence>" +
    "</QueryOptions>" +
    "</queryOptions>" +
    "</GetListItems>" +
    "</soap:Body></soap:Envelope>";

  const requestHeaders: Headers = new Headers();
  requestHeaders.append('Content-type', "text/xml; charset=\"utf-8\"");
  const httpClientOptions: IHttpClientOptions = {
    body: xmlCall,
    headers: requestHeaders
  };

  console.log("About to make REST API request.");

  return this.context.httpClient.post(
    wsURL,
    HttpClient.configurations.v1,
    httpClientOptions)
    .then((response: HttpClientResponse) => {
      console.log("REST API response received.");
      console.log(response);
      console.log(response.text());
      console.log(response.json());
      debugger;
      return response.json();
    });
}

如何从 TypeScript 中的 Sharepoint 框架对 soap 网络服务执行 post 并获得 xml 响应?

好吧,我一切正常。

问题是您不能在 ASYNC post 调用中添加调试器代码,因此永远不会起作用。其次,从 SOAP post 到 lists.asmx 的响应不是 HttpClientResponse 类型的响应,而只是带有 xml.

的普通字符串

所以函数现在看起来像这样:

private makeRequest(listName: string): Promise<string> {

let wsURL = this.context.pageContext.web.absoluteUrl + "/_vti_bin/Lists.asmx";
var xmlCall = `
                <soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
                  <soap:Body>
                    <GetListItems xmlns="http://schemas.microsoft.com/sharepoint/soap/">
                      <listName>${listName}</listName>
                      <query>
                        <Query>
                          <Where>
                            <DateRangesOverlap>
                              <FieldRef Name="EventDate" />
                              <FieldRef Name="EndDate" />
                              <FieldRef Name="RecurrenceID" />
                              <Value Type="DateTime"><Year/></Value>
                            </DateRangesOverlap>
                          </Where>
                        </Query>
                      </query>
                      <queryOptions>
                        <QueryOptions>
                          <ExpandRecurrence>TRUE</ExpandRecurrence>
                        </QueryOptions>
                      </queryOptions>
                    </GetListItems>
                  </soap:Body>
                </soap:Envelope>
`;

  const requestHeaders: Headers = new Headers();
  requestHeaders.append('Content-type', "text/xml; charset=\"utf-8\"");
  const httpClientOptions: IHttpClientOptions = {
    body: xmlCall,
    headers: requestHeaders
  };

  console.log("About to make REST API request.");

  return this.context.httpClient.post(
    wsURL,
    HttpClient.configurations.v1,
    httpClientOptions)
    .then(data => {
      var result: any[];
      if(data.status == 200)
      {
        return data.text(); //returning the XML text of the response
      }
      else
      {
        return "";
      }
    });
}

函数是这样调用的

      this.makeRequest(this.properties.listdropdown)
      .then((data) => {
        let vArrEvents:any[] = [];
        $(data).find("listitems").children().children().each((index, element) => {
          let ids = $(element).attr("ows_UniqueId").split(";");
          let rec = $(element).attr("ows_fRecurrence");
          let strMatch:any[] = $(element).attr("ows_EventDate").match(/^(\d+)-(\d+)-(\d+) (\d+)\:(\d+)\:(\d+)$/);
          let startDate = new Date(strMatch[1], strMatch[2] - 1, strMatch[3], strMatch[4], strMatch[5], strMatch[6]);
          let today = new Date();
          today.setHours(0,0,0);
          if(startDate >= today)
          {
            vArrEvents.push({
                  "StartTime": $(element).attr("ows_EventDate"),
                  "EndTime": $(element).attr("ows_EndDate"),
                  "Title": $(element).attr("ows_Title"),
                  "Recurrence": (rec === "1" ? true : false),
                  "Description": $(element).attr("ows_Description"),
                  "Guid": ids[1],
                  "Id": ids[0],
              });
          }
        });
        this.showEvents(vArrEvents);
        this.context.statusRenderer.clearLoadingIndicator(this.domElement);
      });