是否可以使用泛型方法的web api

本文关键字:web api 泛型方法 可以使 是否 | 更新日期: 2023-09-27 18:07:46

我通过从各种MVC控制器进行httpclient调用从web api获取数据。因为我必须做很多次,所以我做了一个泛型方法,我可以通过传入api url和模型返回类型来重用它。它工作得很好,但我担心我失去了机会,有不同的方法,如GetPeople, GetPersonById等。我所做的有什么不好的地方吗?

Utilities.cs:

    public static T GetDataFromWebService<T>(T model, string svcEndPoint)
    {
        HttpClient client = new HttpClient(new HttpClientHandler() { UseDefaultCredentials = true });
        client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
        var response = client.GetAsync(svcEndPoint).Result;
        var result = response.Content.ReadAsAsync<T>().Result;
        return result;
    }

控制器:

        string svc = appSettings.GetPeopleApiUrl;
        var model = new List<Person>();
        var people = Utilities.GetDataFromWebService <IEnumerable<Person>>(model, svc);

是否可以使用泛型方法的web api

你仍然可以有专门的方法,如GetPeople, GetPersonById,通过将它们分层在顶部:

PeopleModel GetPeople(...) {
 return GetDataFromWebService<PeopleModel>(...);
}

没有缺点,把所有样板代码放在一个共享的实用程序方法中是很好的。

好吧,肯定有更好的方法来完成整个实现,但如果我必须坚持这个问题,我会说任何减少耦合的尝试都是未来方向的良好一步。在您的情况下,由于您正在抽象出对实用程序方法进行服务调用的责任,因此从长远来看,它将对您有所帮助。

虽然我建议不要把这些塞在实用程序类中,你应该让连接成为它自己的类,就像这样

public delegate T ParseToObject<T>(string response);
public class ServiceConnector : IServiceConnector
{
    public string LogoffUrl { get; set; }
    public bool SupportRetry { get; set; }        
    private WebClient _client;
    public ServiceConnector()
    {
    }
    public T GetResponse<T>(string requestUrl, ParseToObject<T> parsingMethod)
    {
        string response = __getResponse(requestUrl);
        return parsingMethod(response);
    }     
    private string __getResponse(string requestUrl)
    {
        string serviceResponse = string.Empty;
        try
        {
            __initializeWebClient();
            Logger.Current.LogInfo(string.Format("Sending request with URL {0}", requestUrl));
            serviceResponse = _client.DownloadString(requestUrl);
        }
        catch (Exception ex)
        {
            if (ex.Message != null) 
            {
            Logger.Current.LogException(string.Format("Exception during OvidWS request {0} ", requestUrl), ex); 
                _client = null;
            }
          //Sample implementation only, you could throw the exception up based on your domain needs
        }
        return serviceResponse;
    }
    private void __initializeWebClient()
    {
        if (_client == null)
            _client = new WebClient();
    }
}

有了这个,明天,假设你想添加支持注销,支持cookie,支持凭据,支持重试,这是你唯一可以舒适地进行更改的地方。同样,如果您想在其他地方使用Webclient,您也可以在这里做得更好。

试试这个帮助器:

 public static class WebClientExtension
{
    public static T DownloadSerializedJsonData<T>(string url) where T : new()
    {
        var contentType = ConfigurationManager.AppSettings["ContentType"];//content type in app config or web config
        using (var webClient = new WebClient())
        {
            webClient.Headers.Add("Content-Type", contentType);
            var jsonData = string.Empty;
            try
            {
                jsonData = webClient.DownloadString(url);
            }
            catch (Exception ex)
            {
                throw ex;
            }
            return !string.IsNullOrEmpty(jsonData) ? JsonConvert.DeserializeObject<T>(jsonData) : new T();
        }
    }
    public static T AuthorizationContentSerializedJsonData<T>(string url) where T : new()
    {
        string jsonData = null;
        try
        {
            var httpRequest = (HttpWebRequest)WebRequest.Create(url);
            //ClientBase.AuthorizeRequest(httpRequest, Authorization.AccessToken);
            var response = httpRequest.GetResponse();
            Stream receiveStream = response.GetResponseStream();
            var readStream = new StreamReader(receiveStream, Encoding.UTF8);
            jsonData = readStream.ReadToEnd();
            response.Close();
        }
        catch (Exception ex)
        {
            throw ex;
        }
        return !string.IsNullOrEmpty(jsonData) ? JsonConvert.DeserializeObject<T>(jsonData) : new T();
    }
}

内容类型

的应用配置/Web配置示例
<add key="ContentType" value="application/hal+json; charset=UTF-8" />