通过 httpclient mvvmcross 发布 Json

Posted

技术标签:

【中文标题】通过 httpclient mvvmcross 发布 Json【英文标题】:Json post via httpclient mvvmcross 【发布时间】:2017-02-07 09:31:25 【问题描述】:

我在 MVVMCROSS 解决方案 (Xamarin) 中通过 HttpClient 对象发送 JSON POST 时遇到问题。 MVVMCROSS 只是一个用于跨平台的模型视图 ViewModel 框架,例如Droid、ios、Windows 等

所以解决方案是这样的:

 --Core (where I have my ViewModels and Services)
 --Droid (android Layout etc)
 --iOS (Not used currently)

在核心内部,我有通过 IoC(控制反转,类似于依赖注入)初始化的服务类

我有这个很棒的 AP​​I,我可以通过 JSON Post 请求使用它。 API 进行人脸识别并返回人脸的“情绪”(愤怒、中性、快乐等)

要使用它,我的 JSON 应该是这样的


    "url" : "http://previews.123rf.com/images/kadettmann/kadettmann1508/kadettmann150800099/43824672-Handsome-argentinian-guy-at-beach-Stock-Photo-happy.jpg"

到目前为止一切顺利,现在 POST url 是:https://api.projectoxford.ai/emotion/v1.0/recognize 我猜似乎不难!

我还需要发送两个标头:

Content-Type = application/json
Ocp-Apim-Subscription-Key = My super awesome secret key

如果是通过 POSTMAN(Chrome 插件)发送这个 JSON,我会得到预期的结果:

[
  
    "faceRectangle": 
      "height": 312,
      "left": 563,
      "top": 208,
      "width": 312
    ,
    "scores": 
      "anger": 0.00000000112,
      "contempt": 0.000000049,
      "disgust": 0.0000000035,
      "fear": 0.000000000106,
      "happiness": 0.99999994,
      "neutral": 0.000000000238,
      "sadness": 0.00000000005,
      "surprise": 0.00000000160
    
  
]

所以现在我正在尝试为 Android 和 iOS 制作一个 MVVMCROSS 应用程序,它将这个 JSON 发送到 Microsoft 的服务器。

我使用的方法是这样的:

public async Task<bool> RestRequestSucces(string secret, string jsonSerialized)

    bool result = false;    

    try
    
        HttpResponseMessage response;

        using (var httpClient = new HttpClient())
        
            var request = new StringContent(jsonSerialized);
            request.Headers.ContentType = new MediaTypeHeaderValue("application/json");

            httpClient.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", secret);

            response = await httpClient.PostAsync(new Uri("https://api.projectoxford.ai/emotion/v1.0/recognize"), request);

            result = true;
        
    
    catch (Exception e)
    
        string error = e.Message;
        result = false;
    
    return result;

要序列化的 JsonObject 如下所示:

public class URLObject

    public string url  get; set; 

为了序列化我使用这个的对象

private IMvxJsonConverter serializer = Mvx.Resolve<IMvxJsonConverter>();
serializer.SerializeObject(urlObject);

但是在response = await httpClient.PostAsync 我的代码挂起。它不会继续前进。

我这样调用方法RestRequestSucces

IRestService restService = Mvx.Resolve<IRestService>();
restService.RestRequestSucces(secret, jsonSerialized);

这一切都发生在核心项目中。

我的 AndroidManifest.xml 如下所示:

...
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <application android:label="@string/ApplicationName" android:icon="@drawable/Icon" android:theme="@style/MyTheme"></application>
</manifest>

如果有人可以告诉我如何在 CORE 项目中通过 MVVMCROSS 发布一个“简单”的 JSON,那就太棒了!!

【问题讨论】:

这个问题与MvvmCross无关。它只是 HttpClient 和 Json 相关的。你可以简化它。您是否在 catch 语句上设置了断点以查看问题所在? 也试试这个:new StringContent(jsonSerialized, Encoding.UTF8, "application/json") 我都做过,结果HttpClient 在某些 TLS/SSL 站点上存在问题,不知道为什么。我改用ModernHttpClient,问题解决了,看我的回答 【参考方案1】:

自己解决了,

原来HttpClient 在某些 TLS/SSL 网站 (https) 上有问题。通过使用ModernHttpClient 解决了我的问题!

其余代码保持不变,只是HttpClient构造函数不同

using (var httpClient = new HttpClient(new NativeMessageHandler()))

    ....

NativeMessageHandler 是一个HttpClientHandler,可以在ModernHttpClient 中找到,代码如下所示:

namespace ModernHttpClient

    public class NativeMessageHandler : HttpClientHandler
    
        public NativeMessageHandler();
        public NativeMessageHandler(bool throwOnCaptiveNetwork, bool customSSLVerification, NativeCookieHandler cookieHandler = null);

        public bool DisableCaching  get; set; 

        public void RegisterForProgress(HttpRequestMessage request, ProgressDelegate callback);
        [AsyncStateMachine(typeof(<SendAsync>c__async0))]
        [DebuggerStepThrough]
        protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken);
    

希望你们可以使用它! 链接到github上的ModernHttpClient。

【讨论】:

以上是关于通过 httpclient mvvmcross 发布 Json的主要内容,如果未能解决你的问题,请参考以下文章

如何通过 Xamarin MvvmCross 中的 BottomNavigationView 在视图模型之间导航

httpclient发邮件

MVVMCross 和 Zumero 同步

将 Xamarin.UITest 与 MvvmCross 绑定一起使用

如何在 iOS 中使用没有故事板的 MvvmCross?

在 Xamarin.Forms MvvmCross 中存储视图