JSON 写入错误中的类型无效,尝试通过 JSON 将自定义类发送到 .NET Web 服务

Posted

技术标签:

【中文标题】JSON 写入错误中的类型无效,尝试通过 JSON 将自定义类发送到 .NET Web 服务【英文标题】:Invalid type in JSON write error trying to send custom class via JSON to .NET web service 【发布时间】:2017-05-03 20:46:51 【问题描述】:

我正在尝试将数据发送到接受三个参数类型为(字符串、字符串、QBUser 类)的 .NET Web 服务。在 javascript 中,我会像这样以 JSON 格式发送参数:

sKey: "key", sUpdatetype: "edit", oQbUser: QBUser 

我以前从未遇到过该方法的任何问题,.NET 将能够将其正确分类到服务器上的类对象中。使用 Swift,我已经成功地发送了本书中几乎所有类型的 JSON,但是我在发送自定义类/结构作为参数时遇到了问题。这是我当前的代码:

func updateQbUser(k: String, t: String, oUser: QBUUser, completion: @escaping (_ oVisits: AnyObject) -> ()) 
    let params: [String: Any] = ["sKey": k, "sUpdateType": t, "iObjectId": oUser]
    let url = URL(string: "myWebService.asmx/updateQbUser")!
    let session = URLSession.shared
    var request = URLRequest(url: url)
    request.httpMethod = "POST"
    do  request.httpBody = try JSONSerialization.data(withJSONObject: params, options: .prettyPrinted)  catch let error  print(error.localizedDescription) 
    request.addValue("application/json", forHTTPHeaderField: "Content-Type")
    request.addValue("application/json", forHTTPHeaderField: "Accept")
    let task = session.dataTask(with: request as URLRequest, completionHandler:  data, response, error in
        guard error == nil else  return 
        DispatchQueue.main.async  completion(response!) 
    )
    task.resume()

控制台显示的错误如下:

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Invalid type in JSON write (QBUUser)'

QBUUser 类不是 NSString、NSNumber、NSArray、NSDictionary 或 NSNull 的实例,所以我一直不知道如何将它传递给服务器。

在尝试发送之前,有没有办法将 QBUUser 类转换为上面列出的任何对象类型?我试图在类上运行一个循环,那是一个完全不同的锤子包,但得到了一些关于不能 AnyHashable over Array Literal 或类似的错误。有没有更好的方法我还没有发现?

参数必须是这样的,所以我被困在那里。我只需要将类发送到另一端,因为它本质上只是在键/值对中。

这是类在控制台中打印出来的样子:

  [QBUUser]:
  ID:20786
  created at:2017-05-03 15:05:56 +0000
  updated at:2017-05-03 20:16:52 +0000
  externalUserID:2456369827
  blobID:0
  facebookID:(null)
  twitterID:(null)
  twitterDigitsID:(null)
  full name:Erik Grosskurth
  email:erik@webgraphicsatlanta.com
  login:Erik_2456369827
  phone:(null)
  tags:(
    ""
)
  lastRequestAt:2017-05-03 20:20:16 +0000
  customData:(null)
  website:(null)

【问题讨论】:

【参考方案1】:

您很可能只需将您的QBUUser 对象转换为字典。您可以内联执行此操作,但如果您打算重用该功能,您也可以创建一个辅助函数来执行此操作。

字典应该看起来像这样:

let qbuUser = QBUUser() //presumably you already have a reference to the user in question
let user: [String : Any] = ["id" : qbuUser.ID, "createdAt" : qbuUser.createdAt, "updatedAt" : qbuUser.updatedAt, ...]

如果您想在 QBUUser 类中创建一个辅助方法,您可以执行以下操作:

extension QBUUser 
   func toDictionary() -> [String : Any] 
      return ["id", self.ID, "createdAt", self.createdAt, ...]
   

这将允许您将现有功能更改为如下所示:

let params: [String: Any] = ["sKey": k, "sUpdateType": t, "iObjectId": oUser.toDictionary()]

还可能值得指出的是,参数中 QBUUser 对象的键是“iObjectId”,这(对我而言)意味着他们所需要的只是来自用户的 ID,这使得整个解决方案没有实际意义。

【讨论】:

以上是关于JSON 写入错误中的类型无效,尝试通过 JSON 将自定义类发送到 .NET Web 服务的主要内容,如果未能解决你的问题,请参考以下文章

尝试使用 JSONModel 序列化后出错:JSON 写入中的类型无效 (...)

在 Swift 中写入 JSON 中的***类型无效

Swift - JSON 写入中的***类型无效

iOS 中的 JSON 错误:JSON 写入中的***类型无效

JSONSerialization JSON 写入中的类型无效 (_SwiftValue)

JSONSerialization JSON 写入中的类型无效 (_SwiftValue)