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