Visual Studio On Mac模型缺少字段

时间:2018-01-07 10:51:46

标签: c# visual-studio xamarin xamarin.ios visual-studio-2017

我在MAC上有Visual Studio Community Edition 2017,正在开发Xamarin.iOS应用程序,我面临着奇怪的问题。

  • 我有PCL,我用它的模型创建了HttpClient(请求和每个API调用的响应)。
  • 我使用PCL中的模型(初始化和分配值)从Xamarin.iOS app生成post请求对象。
  • 我从Xamarin.iOS app
  • 调用post方法
  • 现在我在PCL中获取post请求对象始终为null!当作为字符串阅读时,它是{}
  • 然后我尝试使用其中一个模型跟踪问题(包含EmailAddressFullName),因此在调用客户端发布方法之前在Xamarin.iOS应用中添加了Console.WriteLine(searchRequest.EmailAddress) (只知道这个问题的根源在哪里)
  • 现在在PCL中,我只获得EmailAddress字段{"EmailAddress" : "sample@domain.com"}
  • 在我尝试添加Console.WriteLine(searchRequest.FullName)之后,我能够获得正确的对象{"EmailAddress" : "sample@domain.com", "FullName" : "Sample Full Name"} !!!

来自Xamarin.iOS app的请求:

APIClient client = new APIClient();
SearchRequest searchRequest = new SearchRequest
{
  EmailAddress = "sample@domain.com",
  FullName = "Sample Full Name"
};
var result = await client.Search(searchRequest);

PCL客户端模型对象:

public class SearchRequest
{
public string FullName {get; set;}
public string EmailAddress {get;set}
}

PCL HTTP客户端:

public async Task<SearchResult> Search(SearchRequest requestObj)
{
    SearchResult res = new SearchResult();
    StringContent content = new StringContent(JsonConvert.SerializeObject(requestObj, Formatting.None, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }), Encoding.UTF8, "application/json"); // Content as string will be {}
    HttpResponseMessage response = await client.PostAsync($"{baseURL}ApplicationSearch", content);
    return JsonConvert.DeserializeObject<SearchResult>(responseString);
}

如果我在var result = await client.Search(searchRequest);之后在Xmarin.iOS应用中添加以下两行:

Console.WriteLine(searchRequest.EmailAddress);
Console.WriteLine(searchRequest.FullName);

现在StringContent对象将具有:

{"EmailAddress" : "sample@domain.com", "FullName" : "Sample Full Name"}

任何人都可以解释一下这里发生了什么吗?

1 个答案:

答案 0 :(得分:2)

在构建Xamarin.iOS应用程序时,它会运行托管代码的链接器,用于删除未使用的代码,从不访问这些代码以减少应用程序的大小。在您的情况下,永远不会直接访问属性,只能通过Json.Net中的反射来访问。

但是当您至少访问过一次属性时,它们会包含在生成的二进制文件中,因此Json.Net可以找到它们。

要确保即使不直接访问您的自定义类成员,也可以向您的班级添加Preserve属性:

[Preserve(AllMembers=true)]
public class SearchRequest
{
   ...
}

您的PCL中也可能需要此属性。幸运的是,您可以手动定义它,因为链接器只是按名称查找属性:

public sealed class PreserveAttribute : System.Attribute {
    public bool AllMembers;
    public bool Conditional;
}

您可以在official documentation

中查看有关此主题的更多详细信息