【问题标题】:Sending "complex" model data over UnityWebRequest通过 UnityWebRequest 发送“复杂”模型数据
【发布时间】:2019-08-30 19:35:08
【问题描述】:

我正在尝试在我的 Unity 项目中使用一些简单的 .NET API。通过手动指定每个字段的名称,我已经能够在 API 服务器上填充模型(类)。问题是这些模型的内容主要是原始数据类型,主要是整数和字符串。我的模型结构将需要嵌套模型(类),例如:

public class Echo
{
    public string text { get; set; }
}

public class ComplexData
{
    public List<Echo> echo { get; set; }
    public string description { get; set; }
}

我在 Unity 中有完全相同的模型,serializable,并且没有 getter 和 setter,因为这是我在研究中看到的。

所以这是我用来发送这个模型的代码,它在发送到这个函数之前填充(并通过断点确认)。 请记住,我尝试过 WWWFormDictionaryIMultipartFormSection 数据类型无济于事。我将它们留在代码中只是为了演示我迄今为止所做的尝试:

IEnumerator sendComplexModel(string url, ComplexData complexData)
{
    string complex = JsonUtility.ToJson(complexData);

    WWWForm form = new WWWForm();
    form.AddField("complexData", complex);

    Dictionary<string, string> keyValuePairs = new Dictionary<string, string>();
    keyValuePairs.Add("complexData", complex);

    List<IMultipartFormSection> formData = new List<IMultipartFormSection>();
    formData.Add(new MultipartFormDataSection("complexData", complex));

    UnityWebRequest uwr = UnityWebRequest.Post(url, formData);
    yield return uwr.SendWebRequest();

    if (uwr.isNetworkError)
    {
        Debug.Log("Something went wrong");
    }
    else
    {
        Debug.Log(uwr.downloadHandler.text);
    }
}

您可以假设我已经更新了参数:UnityWebRequest uwr = UnityWebRequest.Post(url, formData); 以使用我在上面创建的相关数据结构进行测试

UnityWebRequest 的每个重载函数都将 null 传递给 .NET,如 Visual Studio 的此屏幕截图所示:

我做错了什么?使用标准的 Unity 库是否可以实现这样的功能?我宁愿坚持使用 UnityWebRequest 或 Unity 中内置的任何类似库。

这是两个模型(类)的并排,左边是 .NET API,右边是 Unity:

任何帮助将不胜感激,在此先感谢。

=====================更新=======================

@LukeBriggs

我已经按如下方式实现了您的代码,再次进行完整性检查,在网络调用之前添加一个断点以仔细检查我实际上是在发送一个填充模型。

这就是我更新代码的方式:

    string complex = JsonUtility.ToJson(complexData);
    UnityWebRequest uwr = UnityWebRequest.Post(url, complex);
    uwr.SetRequestHeader("Content-Type", "application/json");

    yield return uwr.SendWebRequest();

    if (uwr.isNetworkError)
    {
        Debug.Log("Something went wrong");
    }
    else
    {
        Debug.Log(uwr.downloadHandler.text);
    }

Visual Studio 现在通过空引用异常,而以前它只会显示模型属性/字段为空。截图:

【问题讨论】:

  • 您的语言有点混乱..“模型”您似乎实际上指的是classes,而那些不是“函数”而是“字段”
  • @derHugo 抱歉,我在编辑中澄清了我对函数的使用。术语模型只是 MVC 编码模式中一个类的特定用途,我的 API 是在其中构建的,我只是在我的 Unity 项目中继续这种编码模式。
  • 也只是一个一般性的旁注:可能希望避免调用诸如“ComplexData”之类的东西,因为随着项目的增长,它会很快变得混乱。始终以它们所代表的内容命名你的类。 “UserProfileData”等
  • 太棒了-只是想确定一下:P
  • 针对您的编辑更新了答案 - 在您的代码中发现了其他内容:)

标签: c# asp.net visual-studio rest unity3d


【解决方案1】:

内容类型很重要

首先,将 Unity 视为常规 JSON API 的任何其他客户端。然后目标是让 Unity 发送 JSON 结构化数据。

提示:您还可以创建一些 JSON 并将其发布到您的 API 中,使用 postman、curl 等工具,甚至只是 Web 浏览器中的 devtools 来测试 API 方面。

所以,您目前非常接近这一点。缺少的关键部分只是您的标题。发出 POST 请求时,您必须指定您实际发送的数据格式 - 这是由 Content-Type 标头完成的。标准默认是多部分表单内容类型,它不支持这种嵌套数据,但 JSON 支持。以下是在 Unity 中指定“我正在发布 JSON”的方式:

string jsonToSend = JsonUtility.ToJson(complexData);

UnityWebRequest uwr = UnityWebRequest.Post(url, "");
uwr.uploadHandler = new UploadHandlerRaw(System.Text.Encoding.UTF8.GetBytes(jsonToSend));
uwr.SetRequestHeader("Content-Type", "application/json"); // <--- The missing magic line
yield return uwr.SendWebRequest();

..

[FromBody] 也很重要

在您的 API 中,尝试添加 [FromBody] 参数属性,如下所示:

public string getComplexData([FromBody] ComplexData complexData)
{
..
}

【讨论】:

  • 感谢@LukeBriggs 不知何故,该模型仍未被 API 接收,然而,奇怪的是,在 API 方面,VS 现在抛出了一个空引用异常,它以前没有这样做。它只是说模型字段为空。
  • 我刚刚再次编辑了一个更改,使其对不同版本的 Unity 更加通用 - .Post 方法已经更改了几次,因此无论您是哪个版本,以上都应该是好的上:)
  • 请回复您的 PostMan 提示,我已成功让以下 API 在 Unity 中工作,以至于我可以在客户端解析模型数据,并将模型发布到 API 中而无需嵌套: public ComplexData getComplexData(string text) public string(Echo echo) 我还确认我的 API 正在使用 newtonsoft 与 Windows 控制台应用程序一起使用
  • 非常感谢,您上次的更新已解决!整个晚上都在拉我的头发哈哈
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-03
  • 2017-06-08
  • 2014-06-06
  • 2016-09-26
相关资源
最近更新 更多