是否可以使用泛型方法的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);
你仍然可以有专门的方法,如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" />