通过 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(控制反转,类似于依赖注入)初始化的服务类
我有这个很棒的 API,我可以通过 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 在视图模型之间导航