是否可以使用web API的通用方法?

时间:2015-08-13 20:46:33

标签: c# generics asp.net-web-api

我通过从各种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);

3 个答案:

答案 0 :(得分:1)

您仍然可以使用GetPeople, GetPersonById之类的专门方法,将它们分层放在顶层:

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

没有缺点,您可以在共享实用程序方法中使用所有样板代码。

答案 1 :(得分:1)

嗯,确实有更好的方法来进行整体实施,但如果我必须坚持这个问题,我会说任何减少耦合的尝试都是未来方向的一个很好的步骤。在您的情况下,由于您正在逐渐消除对实用程序方法进行服务调用的责任,因此从长远来看它会对您有所帮助。

虽然我建议不要在Utility类中将它们拼凑在一起,你应该将它连接成自己的类,就像这样

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,你也可以在这里做得更好。

答案 2 :(得分:0)

尝试使用该助手:

 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" />