swift 3, wcf service

2020-05-01 12:37发布

I am trying to use an existing WCF service in an IOS APP coded in swift 3. The problem seem to be in the format of the envelope.

The service is on line and work well (is already used by an android app)

URL of the service: www.esmnovara.it\FitnessManagerService.svc

This is the request, seen from a WCF test client:

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
  <s:Header>
    <Action s:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">http://tempuri.org/FitnessManagerIService/Login</Action>
  </s:Header>
  <s:Body>
    <Login xmlns="http://tempuri.org/">
      <NomeUtente></NomeUtente>
      <Password></Password>
    </Login>
  </s:Body>
</s:Envelope>

It must return this:

"
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
  <s:Header />
  <s:Body>
    <LoginResponse xmlns="http://tempuri.org/">
      <LoginResult>0|ERRORE GENERICO, RIVOLGERSI ALLA RECEPTION</LoginResult>
      <NomeUtente a:nil="true" xmlns:a="http://www.w3.org/2001/XMLSchema-instance" />
      <Password a:nil="true" xmlns:a="http://www.w3.org/2001/XMLSchema-instance" />
    </LoginResponse>
  </s:Body>
</s:Envelope>
"

This is the code of my IOS swift 3 app:

 var soapMessage : String = ""
    soapMessage += "<s:Envelope xmlns:s='http://schemas.xmlsoap.org/soap/envelope/'>"
    soapMessage += "<s:Header>"
    soapMessage += "<Action s:mustUnderstand='1' xmlns='http://schemas.microsoft.com/ws/2005/05/addressing/none'>http://tempuri.org/FitnessManagerIService/Login</Action>"
    soapMessage += "</s:Header>"
    soapMessage += "<s:Body>"
    soapMessage += "<Login xmlns='http://tempuri.org/FitnessManagerIService/Login'>"
    soapMessage += "<NomeUtente></NomeUtente>"
    soapMessage += "<Password></Password>"
    soapMessage += "</Login>"
    soapMessage += "</s:Body>"
    soapMessage += "</s:Envelope>'"


    let urlString = "http://www.esmnovara.it/FitnessManagerService.svc"


    let url = URL(string: urlString)

    let theRequest = NSMutableURLRequest(url: url!)

    let msgLength = soapMessage.characters.count

    theRequest.addValue("text/xml; charset=utf-8", forHTTPHeaderField: "Content-Type")
    theRequest.addValue(String(msgLength), forHTTPHeaderField: "Content-Length")
    theRequest.httpMethod = "POST"
    theRequest.httpBody = soapMessage.data(using: String.Encoding.utf8, allowLossyConversion: false) // or false

    let connection = NSURLConnection(request: theRequest as URLRequest, delegate: self, startImmediately: true)
    connection!.start()

    if (connection != nil) {
        var mutableData : Void = NSMutableData.initialize()


        //debugPrint(mutableData)
    }

And this is what I get:

"IIS 8.5 Detailed Error - 400.0 - Bad Request"
"HTTP Error 400.0 - Bad Request"
"Bad Request"
"Detailed Error Information:"
"Module"
"IsapiModule"
"Notification"
"ExecuteRequestHandler"
"Handler"
"svc-ISAPI-4.0_32bit"
"Error Code"
"0x00000000"
"Requested URL"
"http://www.esmnovara.it:80/FitnessManagerService.svc"
"Physical Path"
"D:\\inetpub\\webs\\esmnovarait\\FitnessManagerService.svc"
"Logon Method"
"Anonymous"
"Logon User"
"Anonymous"
"Request Tracing Directory"
"D:\\LogFiles\\FailedReqLogFiles"
"More Information:"
" \n  The request could not be understood by the server due to malformed syntax. \n  "
"View more information "
"Microsoft Knowledge Base Articles:"

Can anyone help me?

标签: wcf swift3
1条回答
淡お忘
2楼-- · 2020-05-01 13:00

I wrote a little playground script which seems to work:

import UIKit
import PlaygroundSupport

// Ignore the next line, it's just to avoid a annoying message in Playgrounds
URLCache.shared = URLCache(memoryCapacity: 0, diskCapacity: 0, diskPath: nil)

// Service URL
let serviceUrl = URL(string: "http://www.esmnovara.it/FitnessManagerService.svc")
// Service request using the serviceURL
var serviceRequest = URLRequest(url: serviceUrl!)

// Set a couple of headers
serviceRequest.addValue("text/xml; charset=utf-8", forHTTPHeaderField: "Content-Type")
serviceRequest.addValue("http://tempuri.org/FitnessManagerIService/Login", forHTTPHeaderField: "SOAPAction")

// Set the http verb
serviceRequest.httpMethod = "POST"

// Soap message
let soapMessageAsText = "<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\"><s:Body><Login xmlns=\"http://tempuri.org/\"><NomeUtente/><Password/></Login></s:Body></s:Envelope>"
// Enconded as data
let soapMessageAsData = soapMessageAsText.data(using: String.Encoding.utf8)
// Set message as data in the http body of the request
serviceRequest.httpBody = soapMessageAsData

// Call the service using URLSession
URLSession.shared.dataTask(with: serviceRequest) { (data, response, error) in
   // Check for error
   guard error == nil else {
      print(error ?? "Unknown error")
      return
   }
   // Display data as string
   let dataAsString = String(data: data!, encoding: String.Encoding.utf8)
   print(dataAsString)

   }.resume()

// Ignore this line, it's neccesary so that playground waits
PlaygroundPage.current.needsIndefiniteExecution = true

Hope it works.

查看更多
登录 后发表回答