简化并统一程序获取WebApi对应实体数据的过程,方便对实体进行扩充。原理就是数据服务使用反射发现数据提供者,处理好泛型就行。
相关传送门:Restful WebApi开发实践
先来看下最后的请求效果:(插件服务总线用的是服务定位器设计模式)
PRivate IModelDataService MDS = BundleServiceBus.Current.GetInstance<IModelDataService>();//获取对应实体数据MDS.GetDataByModel<EntityModel, Guid>(new DataParameter{ TenantId = XXX, AggregationId = XXX, SiteId = XXX, CMD = "?xxx=xxx",});//带Id获取MDS.GetDataByModel<EntityModel, Guid>(new DataParameter<Guid>{ TenantId = XXX, AggregationId = XXX, SiteId = XXX, DataId = XXX, CMD = "?xxx=xxx",});
HTTP通讯简单封装:(服务端使用了SSO、OAuth做授权)
public class DataWithOAuth : IDataWithOAuthService, IBundleServiceProvider{ public string LoginUserName { get; private set; } public string accessToken { get; private set; } Uri BaseAddress { get; set; } public DataWithOAuth() { LoginUserName = "[未登录]"; } private HttpClient GetHttpClient() { var client = new HttpClient { BaseAddress = BaseAddress }; client.SetBearerToken(AccessToken); return client; } private OAuth2Client GetOAuth2Client() { return new OAuth2Client( new Uri("[oauthUrl]"), "[oauthClient]", "[oauthSecret]"); } private AccessTokenResponse RequestToken(string username, string passWord, string scope) { var client = GetOAuth2Client(); try { return client.RequestAccessTokenUserName(username, password, scope); } catch (Exception) { return null; } } public bool SetBaseUrl(string baseUrl) { if (!string.IsNullOrWhiteSpace(baseUrl)) BaseAddress = new Uri(baseUrl); return true; } public bool Login(string userName, string passWord) { var token = RequestToken(userName, passWord, "read"); if (token != null) { LoginUserName = userName; AccessToken = token.AccessToken; return true; } return false; } #region 服务 public ReturnHTTPData Get(string url) { try { var hc = GetHttpClient(); var response = hc.GetAsync(url).Result; return new ReturnHTTPData { StatusCode = response.StatusCode.ToString(), ReasonPhrase = response.ReasonPhrase, Version = response.Version.ToString(), Content = response.Content.ReadAsStringAsync().Result }; } catch (Exception ex) { return new ReturnHTTPData { Content = "Err:" + ex.Message }; } } public ReturnHTTPData Post<T>(string url, T Data) { try { var hc = GetHttpClient(); var response = hc.PostAsJsonAsync(url, Data).Result; return new ReturnHTTPData { StatusCode = response.StatusCode.ToString(), ReasonPhrase = response.ReasonPhrase, Version = response.Version.ToString(), Content = response.Content.ReadAsStringAsync().Result }; } catch (Exception ex) { return new ReturnHTTPData { Content = "Err:" + ex.Message }; } } public ReturnHTTPData Put<T>(string url, T Data) { try { var hc = GetHttpClient(); var response = hc.PutAsJsonAsync(url, Data).Result; return new ReturnHTTPData { StatusCode = response.StatusCode.ToString(), ReasonPhrase = response.ReasonPhrase, Version = response.Version.ToString(), Content = response.Content.ReadAsStringAsync().Result }; } catch (Exception ex) { return new ReturnHTTPData { Content = "Err:" + ex.Message }; } } public ReturnHTTPData Delete(string url) { try { var hc = GetHttpClient(); var response = hc.DeleteAsync(url).Result; return new ReturnHTTPData { StatusCode = response.StatusCode.ToString(), ReasonPhrase = response.ReasonPhrase, Version = response.Version.ToString(), Content = response.Content.ReadAsStringAsync().Result }; } catch (Exception ex) { return new ReturnHTTPData { Content = "Err:" + ex.Message }; } } #endregion}
由于HTTP通讯这个服务我需要插件间调用,返回的数据模型我放到了契约项目内,为了不引用其他类库,所以根据需要对HttpResponseMessage的几个属性做了提取:
public class ReturnHTTPData{ public string Content { get; set; } public string StatusCode { get; set; } public string ReasonPhrase { get; set; } public string Version { get; set; } public string ErrorMessage { get { return StatusCode + ":" + ReasonPhrase + " " + Content; } }}
定义数据参数的模型:
public class DataParameter{ public Guid TenantId { get; set; } public Guid AggregationId { get; set; } public Guid SiteId { get; set; } public string CMD { get; set; } public static DataParameter Empty = new DataParameter();}public class DataParameter<IdType> : DataParameter{ public IdType DataId { get; set; } public new static DataParameter<IdType> Empty = new DataParameter<IdType>();}
定义一个数据服务接口:
public interface IModelDataService{ ReturnModelData<DataModelType> GetDataByModel<DataModelType, IdType>(DataParameter dataParam); ReturnModelData<DataModelType> GetDataByModel<DataModelType, IdType>(DataParameter<IdType> dataParam); ReturnModelData<DataModelType> PostDataByModel<DataModelType, IdType>(DataParameter dataParam, DataModelType data); ReturnModelData<DataModelType> PutDataByModel<DataModelType, IdType>(DataParameter<IdType> dataParam, DataModelType data); ReturnModelData<DataModelType> DeleteDataByModel<DataModelType, IdType>(DataParameter<IdType> dataParam);}
返回的数据类型:
public class ReturnModelData<DataModelType> : ReturnHTTPData{ public bool IsSuccess { get; set; } public List<DataModelType> Data { get; set; } public string Message { get; set; }}
实现一个数据服务:
public class ModelDataService : IModelDataService, IBundleServiceProvider{ private Dictionary<Type, object> _data = new Dictionary<Type, object>(); public ModelDataService() { var data = Assembly.GetExecutingAssembly().DefinedTypes.Where(s => s.BaseType == typeof(DataHelperBase)); foreach (var typeInfo in data) { var ife = typeInfo.GetInterfaces(); var dataHelper = Activator.CreateInstance(typeInfo); try { _data.Add(ife.First().GenericTypeArguments[0], dataHelper); } catch (Exception) { } } } public ReturnModelData<DataModelType> GetDataByModel<DataModelType, IdType>(DataParameter dataParam) { object obj; if (_data.TryGetValue(typeof(DataModelType), out obj)) { var dataProvider = obj as IDataProvider<DataModelType, IdType>; if (dataProvider != null) return dataProvider.GetData(dataParam); } return new ReturnModelData<DataModelType> { IsSuccess = false, Message = "未找到[" + typeof(DataModelType) + "]的数据提供者" }; } public ReturnModelData<DataModelType> GetDataByModel<DataModelType, IdType>(DataParameter<IdType> dataParam) { object obj; if (_data.TryGetValue(typeof(DataModelType), out obj)) {
新闻热点
疑难解答