0

我想创建一个 WPF 应用程序来连接到我的 Web api 服务器。但我是 WPF 的新手。更糟糕的是,即使在 .net 中也是如此。

实际上,我已经开始工作了,请按照此http://www.asp.net/web-api/overview/web-api-clients/calling-a-web-api-from-a-wpf-application操作。

经过更多搜索,我发现我完全以错误的方式工作(winform方式)。似乎我应该像大多数社区所说的那样使用MVVM风格。所以我决定重写我所有的代码。

我使用 prism 创建一个模块,并将名称和密码绑定到 ViewModel 类。现在我可以从文本框获取名称和密码。

首先,我没有为每个要使用的 ViewModel 创建一个 httpclient 实例。以下是问题链接

很想统一注册已经构建的实例?

所以我决定写成这样。首先创建接口。

public interface IData
{
    IEnumerable<device> getDevicesByUser(user user);
    IEnumerable<user> getUsers();
    currentUser getCurrentUserInfo();
}

和一个实现接口

public class HttpService : IData
{
    HttpClient client = new HttpClient();
    public HttpService()
    {
        client.BaseAddress = new Uri("https://localhost:3721");
        client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
    }

    public IEnumerable<device> getDevicesByUser(user user)
    {
        throw new NotImplementedException();
    }

    public IEnumerable<user> getUsers()
    {
        throw new NotImplementedException();
    }

    public currentUser getCurrentUserInfo()
    {
        throw new NotImplementedException();
    }
}

后来,我可以在unity中注册实例,并且可以在每个ViewModel中使用它。但是情况是我不能再进一步了。我用了两种方法,但都不起作用。我需要有关正确方法的建议。

第一种方式。我为每个接口方法编写异步方法。

public currentUser getCurrentUserInfo()
    {
      return getCurrentUserInfoFromServer();
    }

private async void getCurrentUserInfoFromServer()
    {
        try
        {
            var response = await client.GetAsync("api/user");
            response.EnsureSuccessStatusCode(); 
            var currentuser = await response.Content.ReadAsAsync<currentUser>();
        }
        catch (Newtonsoft.Json.JsonException jEx)
        {
            MessageBox.Show(jEx.Message);
        }
        catch (HttpRequestException ex)
        {
            MessageBox.Show(ex.Message);
        }
        finally
        {

        }
    }

但似乎 async 不能返回除 void 和 task 以外的类型。而且看起来很奇怪。所以我尝试将所有请求写入一种方法。

private async void getData(string requestUri)
    {
        try
        {
            var response = await client.GetAsync("api/user"+requestUri);
            response.EnsureSuccessStatusCode();
            var ? = await response.Content.ReadAsAsync<?>();
        }
        catch (Newtonsoft.Json.JsonException jEx)
        {
            MessageBox.Show(jEx.Message);
        }
        catch (HttpRequestException ex)
        {
            MessageBox.Show(ex.Message);
        }
        finally
        {

        }
    }

此代码仍然存在与第一个代码相同的问题。不能返回除了void和task以外的类型,另外一个问题是如何获取动态数据?

4

1 回答 1

0

异步方法应该几乎总是返回Taskor Task<T>,因为这就是异步的意思:该方法几乎立即返回,但它实际上还没有完成。所以,要得到它的结果,你await返回的Task. 所以,你的方法看起来像这样:

private async Task<CurrentUser> GetCurrentUserInfoFromServerAsync()
{
    try
    {
        var response = await client.GetAsync("api/user");
        response.EnsureSuccessStatusCode(); 
        var currentuser = await response.Content.ReadAsAsync<currentUser>();
        return currentUser; // sets the result of the returned Task
    }
    catch (Newtonsoft.Json.JsonException jEx)
    {
        MessageBox.Show(jEx.Message);
    }
    catch (HttpRequestException ex)
    {
        MessageBox.Show(ex.Message);
    }
}

这意味着调用的方法GetCurrentUserInfoFromServerAsync()也需要是async,以及that 的方法等,一直到顶部。

此外,将您的关注点分开是一个好习惯:您HttpService不应该显示MessabeBoxes,而只是让异常传播到方法之外。您应该将 UI 处理留给更高层。

于 2013-05-04T12:52:45.860 回答