winforms - 无法从 WinForms 中的模块进行 API 调用
问题描述
当我的启动是 Module 时,api 调用完全杀死了应用程序。我需要我的入口点是一个模块。我怎样才能做到这一点?
Module EDIDownloaderModule
Sub Main(args As String())
ProcessApi()
End Sub
Private Async Sub ProcessApi()
Dim apiUrl As String = "http://localhost:3554/MWAPI/Projects/GetProjectByCustomerAndOrderIds?customerId=abc&customerOrderId=xyz"
Dim apiResult As ApiCallResult(Of Project) = Await ApiCrudCallHelper.Get(Of Project)(apiUrl)
Dim msg As String = apiResult.Message
End Sub
End Module
当我的启动是一个表单时,我可以毫无问题地进行 api 调用
Public Class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
ProcessApi()
End Sub
Private Async Sub ProcessApi()
Dim apiUrl As String = "http://localhost:3554/API/Projects/GetByCustomerAndOrder?customerId=abc&customerOrderId=xyz"
Dim apiResult As ApiCallResult(Of Project) = Await ApiCrudCallHelper.Get(Of Project)(apiUrl)
Dim msg As String = apiResult.Message
End Sub
End Class
这是 API 调用的 Helper 代码
public class ApiCallResult<X> where X : class
{
public HttpStatusCode StatusCode { get; set; }
public string ReasonPhrase { get; set; }
public bool IsError { get; set; }
public bool IsException { get; set; }
public string Message { get; set; }
public X ResponseObject { get; set; } //deserialized object, could be List, int string or just a single object
}
public static class ApiCrudCallHelper
{
/// <summary>
/// Performs Post and returns ApiCallResult
/// </summary>
/// <typeparam name="T">model to Post, could be null, T, List T</typeparam>
/// <typeparam name="X">return model by API, could be X, List X, string </typeparam>
/// <param name="data">data to post of type T, List T</param>
/// <param name="apiUrl">api full URL like http://localhost:65152/API/Test if executing custom action, provide that as well at the end </param>
/// <returns>
/// ApiCallResult
/// StatusCode: status code returned by the API
/// ReasonPhrase: reason phrase returned by the API
/// IsError: true/false
/// IsException: true/false
/// Message: error message, exception message, or result of OK etc results by API
/// X ResponseObject: model returned by the API, it might not be available in all cases. Could be X, List X or string as provided by X above
/// </returns>
public static async Task<ApiCallResult<X>> Post<T, X>(T data, string apiUrl) where X : class
{
var apiCallResult = new ApiCallResult<X> { IsError = true, Message = "No run" };
try
{
//json string
var jsonString = JsonConvert.SerializeObject(data);
using (var client = new HttpClient())
{
var httpContent = new StringContent(jsonString, Encoding.UTF8, "application/json");
var response = await client.PostAsync(apiUrl, httpContent);
var jsonResponseString = await response.Content.ReadAsStringAsync();
//fill
if (response.IsSuccessStatusCode)
{
//deserialize
if (!typeof(X).Equals(typeof(string)))
{
apiCallResult.ResponseObject = JsonConvert.DeserializeObject<X>(jsonResponseString);
}
apiCallResult.IsError = false;
}
else
{
try
{
ApiErrorMessage myMessage = JsonConvert.DeserializeObject<ApiErrorMessage>(jsonResponseString);
if (!string.IsNullOrWhiteSpace(myMessage?.Message))
{
jsonResponseString = myMessage.Message;
}
}
catch (Exception e)
{}
jsonResponseString = jsonResponseString.Trim('"');
}
apiCallResult.StatusCode = response.StatusCode;
apiCallResult.ReasonPhrase = response.ReasonPhrase;
apiCallResult.Message = jsonResponseString;
}
}
catch (Exception ex)
{
apiCallResult.IsException = true;
apiCallResult.Message = ex.Message;
}
return apiCallResult;
}
/// <summary>
/// Performs Put and returns ApiCallResult
/// </summary>
/// <typeparam name="T">model to Post, could be null, T, List T</typeparam>
/// <typeparam name="X">return model by API, could be X, List X, string </typeparam>
/// <param name="data">data to post of type T, List T</param>
/// <param name="apiUrl">api full URL including the Id like http://localhost:65152/API/Test/12345 if executing custom action, provide that as well </param>
/// <returns>
/// ApiCallResult
/// HttpStatusCode StatusCode: status code returned by the API
/// string ReasonPhrase: reason phrase returned by the API
/// bool IsError: true/false
/// bool IsException: true/false
/// string Message: error message, exception message, or result of OK etc results by API
/// X ResponseObject: model returned by the API, it might not be available in all cases. Could be X, List X or string as provided by X above
/// </returns>
public static async Task<ApiCallResult<X>> Put<T, X>(T data, string apiUrl) where X : class
{
var apiCallResult = new ApiCallResult<X> { IsError = true, Message = "No run" };
try
{
//json string
var jsonString = JsonConvert.SerializeObject(data);
using (var client = new HttpClient())
{
var httpContent = new StringContent(jsonString, Encoding.UTF8, "application/json");
var response = await client.PutAsync(apiUrl, httpContent);
var jsonResponseString = await response.Content.ReadAsStringAsync();
//fill
if (response.IsSuccessStatusCode)
{
//deserialize
if (!typeof(X).Equals(typeof(string)))
{
apiCallResult.ResponseObject = JsonConvert.DeserializeObject<X>(jsonResponseString);
}
apiCallResult.IsError = false;
}
else
{
try
{
ApiErrorMessage myMessage = JsonConvert.DeserializeObject<ApiErrorMessage>(jsonResponseString);
if (!string.IsNullOrWhiteSpace(myMessage?.Message))
{
jsonResponseString = myMessage.Message;
}
}
catch (Exception e)
{ }
jsonResponseString = jsonResponseString.Trim('"');
}
apiCallResult.StatusCode = response.StatusCode;
apiCallResult.ReasonPhrase = response.ReasonPhrase;
apiCallResult.Message = jsonResponseString;
}
}
catch (Exception ex)
{
apiCallResult.IsException = true;
apiCallResult.Message = ex.Message;
}
return apiCallResult;
}
/// <summary>
/// Performs Delete and returns ApiCallResult
/// </summary>
/// <typeparam name="X">return model by API, could be X, List X, string. Usually you'll only get Ok result etc for delete, so specify string </typeparam>
/// <param name="apiUrl">api full URL including the Id like http://localhost:65152/API/Test/12345 if executing custom action, provide that as well </param>
/// <returns>
/// ApiCallResult
/// HttpStatusCode StatusCode: status code returned by the API
/// string ReasonPhrase: reason phrase returned by the API
/// bool IsError: true/false
/// bool IsException: true/false
/// string Message: error message, exception message, or result of OK etc results by API
/// X ResponseObject: will only be available if api is returning a model (should not), in most cases it will not be available. Could be X, List X or string as provided by X above
/// </returns>
public static async Task<ApiCallResult<X>> Delete<X>(string apiUrl) where X : class
{
var apiCallResult = new ApiCallResult<X> { IsError = true, Message = "No run" };
try
{
using (var client = new HttpClient())
{
var response = await client.DeleteAsync(apiUrl);
var jsonResponseString = await response.Content.ReadAsStringAsync();
//fill
if (response.IsSuccessStatusCode)
{
//deserialize
if (!typeof(X).Equals(typeof(string)))
{
apiCallResult.ResponseObject = JsonConvert.DeserializeObject<X>(jsonResponseString);
}
apiCallResult.IsError = false;
}
else
{
try
{
ApiErrorMessage myMessage = JsonConvert.DeserializeObject<ApiErrorMessage>(jsonResponseString);
if (!string.IsNullOrWhiteSpace(myMessage?.Message))
{
jsonResponseString = myMessage.Message;
}
}
catch (Exception e)
{ }
jsonResponseString = jsonResponseString.Trim('"');
}
apiCallResult.StatusCode = response.StatusCode;
apiCallResult.ReasonPhrase = response.ReasonPhrase;
apiCallResult.Message = jsonResponseString;
}
}
catch (Exception ex)
{
apiCallResult.IsException = true;
apiCallResult.Message = ex.Message;
}
return apiCallResult;
}
/// <summary>
/// Performs Get and returns ApiCallResult
/// </summary>
/// <typeparam name="X">return model by API, could be X, List X, string. </typeparam>
/// <param name="apiUrl">api full URL </param>
/// <returns>
/// ApiCallResult
/// HttpStatusCode StatusCode: status code returned by the API
/// string ReasonPhrase: reason phrase returned by the API
/// bool IsError: true/false
/// bool IsException: true/false
/// string Message: error message, exception message, or result of OK etc results by API
/// X ResponseObject: Could be X, List X or string as provided by X above
/// </returns>
public static async Task<ApiCallResult<X>> Get<X>(string apiUrl) where X : class
{
var apiCallResult = new ApiCallResult<X> { IsError = true, Message = "No run" };
try
{
using (var client = new HttpClient())
{
var response = await client.GetAsync(apiUrl);
var jsonResponseString = await response.Content.ReadAsStringAsync();
//fill
if (response.IsSuccessStatusCode)
{
//deserialize
if (!typeof(X).Equals(typeof(string)))
{
apiCallResult.ResponseObject = JsonConvert.DeserializeObject<X>(jsonResponseString);
}
apiCallResult.IsError = false;
}
else
{
try
{
ApiErrorMessage myMessage = JsonConvert.DeserializeObject<ApiErrorMessage>(jsonResponseString);
if (!string.IsNullOrWhiteSpace(myMessage?.Message))
{
jsonResponseString = myMessage.Message;
}
}
catch (Exception e)
{ }
jsonResponseString = jsonResponseString.Trim('"');
}
apiCallResult.StatusCode = response.StatusCode;
apiCallResult.ReasonPhrase = response.ReasonPhrase;
apiCallResult.Message = jsonResponseString;
}
}
catch (Exception ex)
{
apiCallResult.IsException = true;
apiCallResult.Message = ex.Message;
}
return apiCallResult;
}
}
解决方案
两个改变奏效了……
- 必须将流程子更改为功能
在 Main 中介绍了 .Wait()
模块 EDIDownloaderModule
Sub Main(args As String()) ProcessApi().Wait() End Sub Private Async Function ProcessApi() As Task(Of Boolean) Dim isRun As Boolean = Await TestHelper.ProcessApi() Return isRun End Function
端模块
推荐阅读
- java - 如何将数据从对话片段发送到 Viewpager 中的所有片段?
- javascript - 谷歌应用脚本消息[j].isUnread()
- unreal-engine4 - 如何防止滚动框在虚幻中消耗触摸事件?
- c++ - 不为 emplace() 定义构造函数的解决方法
- r - 如何在数据框中查找组之间共享的值?
- ethereum - 检索卡在智能合约上的以太币
- sql-server - IF...ELSE 条件总是返回 ELSE 条件
- python - Python 类方法执行多次
- haskell - 在haskell中使用泛型列出构造函数名称
- java - java如何区分Lambda中的Callable和Runnable?