首页 > 学院 > 开发设计 > 正文

C#对WebApi数据操作

2019-11-17 03:00:40
字体:
来源:转载
供稿:网友

C#对WebApi数据操作

目标

简化并统一程序获取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))        {
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表