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))
{
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> PostDataByModel<DataModelType, IdType>(DataParameter dataParam, DataModelType data)
{
object obj;
if (_data.TryGetValue(typeof(DataModelType), out obj))
{
var dataProvider = obj as IDataProvider<DataModelType, IdType>;
if (dataProvider != null) return dataProvider.PostData(dataParam, data);
}
return new ReturnModelData<DataModelType>
{
IsSuccess = false,
Message = "未找到[" + typeof(DataModelType) + "]的数据提供者"
};
}
public ReturnModelData<DataModelType> PutDataByModel<DataModelType, IdType>(DataParameter<IdType> dataParam, DataModelType data)
{
object obj;
if (_data.TryGetValue(typeof(DataModelType), out obj))
{
var dataProvider = obj as IDataProvider<DataModelType, IdType>;
if (dataProvider != null) return dataProvider.PutData(dataParam, data);
}
return new ReturnModelData<DataModelType>
{
IsSuccess = false,
Message = "未找到[" + typeof(DataModelType) + "]的数据提供者"
};
}
public ReturnModelData<DataModelType> DeleteDataByModel<DataModelType, IdType>(DataParameter<IdType> dataParam)
{
object obj;
if (_data.TryGetValue(typeof(DataModelType), out obj))
{
var dataProvider = obj as IDataProvider<DataModelType, IdType>;
if (dataProvider != null) return dataProvider.DeleteData(dataParam);
}
return new ReturnModelData<DataModelType>
{
IsSuccess = false,
Message = "未找到[" + typeof(DataModelType) + "]的数据提供者"
};
}
}
数据提供者
定义一个数据提供者接口:
interface IDataProvider<DataModelType, IdType>
{
ReturnModelData<DataModelType> GetData(DataParameter dataParam);
ReturnModelData<DataModelType> GetData(DataParameter<IdType> dataParam);
ReturnModelData<DataModelType> PostData(DataParameter dataParam, DataModelType data);
ReturnModelData<DataModelType> PutData(DataParameter<IdType> dataParam, DataModelType data);
ReturnModelData<DataModelType> DeleteData(DataParameter<IdType> dataParam);
}
定义数据提供者的基础属性:
abstract class DataProviderBase
{
private IDataWithOAuthService _dwos;
protected IDataWithOAuthService DWOS
{
get
{
if (_dwos == null)
{
_dwos = UppBundleEngine.Constants.BundleService.BundleServiceBus.Current
.GetInstance<IDataWithOAuthService>();
}
return _dwos;
}
}
}
剩下的就是体力活了,实现数据提供者,比如:
class MemberCardModelProvider : DataProviderBase, IDataProvider<MemberCardModel, string>
{
public ReturnModelData<MemberCardModel> GetData(DataParameter dataParam)
{
var result = DWOS.Get("api/XXX/MemberCard/"
+ dataParam.TenantId + "/" + dataParam.AggregationId + "/" + dataParam.SiteId + dataParam.CMD);
if (result.StatusCode == "OK")
{
var model = FastData.GetDataFromJson<MemberCardModel>(result.Content);
return new ReturnModelData<MemberCardModel> { IsSuccess = true, Data = model };
}
return new ReturnModelData<MemberCardModel> { IsSuccess = false, Message = result.ErrorMessage };
}
public ReturnModelData<MemberCardModel> GetData(DataParameter<string> dataParam)
{
var result = DWOS.Get("api/XXX/MemberCard/"
+ dataParam.TenantId + "/" + dataParam.AggregationId + "/" + dataParam.SiteId + "/" + dataParam.DataId + dataParam.CMD);
if (result.StatusCode == "OK")
{
var model = FastData.GetSingleDataFromJson<MemberCardModel>(result.Content);
return new ReturnModelData<MemberCardModel> { IsSuccess = true, Data = new List<MemberCardModel> { model } };
}
return new ReturnModelData<MemberCardModel> { IsSuccess = false, Message = result.ErrorMessage };
}
public ReturnModelData<MemberCardModel> PostData(DataParameter dataParam, MemberCardModel data)
{
var result = DWOS.Post("api/XXX/MemberCard/"
+ dataParam.TenantId + "/" + dataParam.AggregationId + "/" + dataParam.SiteId + dataParam.CMD, data);
if (result.StatusCode == "OK")
{
var model = FastData.GetSingleDataFromJson<MemberCardModel>(result.Content);
return new ReturnModelData<MemberCardModel> { IsSuccess = true, Data = new List<MemberCardModel> { model } };
}
return new ReturnModelData<MemberCardModel> { IsSuccess = false, Message = result.ErrorMessage };
}
public ReturnModelData<MemberCardModel> PutData(DataParameter<string> dataParam, MemberCardModel data)
{
var result = DWOS.Put("api/XXX/MemberCard/"
+ dataParam.TenantId + "/" + dataParam.AggregationId + "/" + dataParam.SiteId + "/" + dataParam.DataId + dataParam.CMD, data);
if (result.StatusCode == "NoContent")
{
return new ReturnModelData<MemberCardModel> { IsSuccess = true };
}
return new ReturnModelData<MemberCardModel> { IsSuccess = false, Message = result.ErrorMessage };
}
public ReturnModelData<MemberCardModel> DeleteData(DataParameter<string> dataParam)
{
var result = DWOS.Delete("api/XXX/MemberCard/"
+ dataParam.TenantId + "/" + dataParam.AggregationId + "/" + dataParam.SiteId + "/" + dataParam.DataId + dataParam.CMD);
if (result.StatusCode == "OK")
{
var model = FastData.GetSingleDataFromJson<MemberCardModel>(result.Content);
return new ReturnModelData<MemberCardModel> { IsSuccess = true, Data = new List<MemberCardModel> { model } };
}
return new ReturnModelData<MemberCardModel> { IsSuccess = false, Message = result.ErrorMessage };
}
}
C#对WebApi数据操作的更多相关文章
- StackExchange.Redis帮助类解决方案RedisRepository封装(字符串类型数据操作)
本文版权归博客园和作者本人共同所有,转载和爬虫请注明原文链接 http://www.cnblogs.com/tdws/tag/NoSql/ 目录 一.基础配置封装 二.String字符串类型数据操作封 ...
- hive数据操作
mdl是数据操作类的语言,包括向数据表加载文件,写查询结果等操作 hive有四种导入数据的方式 >从本地加载数据 LOAD DATA LOCAL INPATH './examples/files ...
- Dapper 数据操作框架
数据操作DapperFrom NuGet:Install-Package DapperorInstall-Package Dapper.StrongName微型ORM:PetaPoco获得PetaPo ...
- Django数据操作F和Q、model多对多操作、Django中间件、信号、读数据库里的数据实现分页
models.tb.objects.all().using('default'),根据using来指定在哪个库里查询,default是settings中配置的数据库的连接名称. 外话:django中引 ...
- coreData数据操作
// 1. 建立模型文件// 2. 建立CoreDataStack// 3. 设置AppDelegate 接着 // // CoreDataStack.swift // CoreDataStackDe ...
- Entity Framework 5.0系列之数据操作
Entity Framework将概念模型中定义的实体和关系映射到数据源,利用实体框架可以将数据源返回的数据具体化为对象:跟踪对象所做的更改:并发处理:将对象更改传播到数据源等.今天我们就一起讨论如何 ...
- 数据操作语言DML与运算符
数据操作语言DML(添加,修改,删除) 1.添加数据 insert into insert into 表名 (字段列表) values (值列表),值列表要和字段列表按顺序匹配. insert int ...
- SQL不同服务器数据库之间的数据操作整理(完整版)
---------------------------------------------------------------------------------- -- Author : htl25 ...
- C#利用SqlDataAdapte对DataTable进行批量数据操作
C#利用SqlDataAdapte对DataTable进行批量数据操作,可以让我们大大简化操作数据的代码量,我们几乎不需要循环和不关心用户到底是新增还是修改,更不用编写新增和修改以及删除的SQL语句, ...
随机推荐
- 详解树莓派Model B+控制蜂鸣器演奏乐曲
步进电机以及无源蜂鸣器这些都需要脉冲信号才能够驱动,这里将用GPIO的PWM接口驱动无源蜂鸣器弹奏乐曲,本文基于树莓派Mode B+,其他版本树莓派实现时需参照相关资料进行修改! 1 预备知识 1.1 ...
- 漫扯:从polling到Websocket
Http被设计成了一个单向的通信的协议,即客户端发起一个request,然后服务器回应一个response.这让服务器很为恼火:我特么才是老大,我居然不能给小弟发消息... 轮询 老大发火了,小弟们自 ...
- ASP.NET Core应用针对静态文件请求的处理[2]: 条件请求与区间请求
通过调用ApplicationBuilder的扩展方法UseStaticFiles注册的StaticFileMiddleware中间件帮助我们处理针对文件的请求.对于StaticFileMiddlew ...
- Git初探--笔记整理和Git命令详解
几个重要的概念 首先先明确几个概念: WorkPlace : 工作区 Index: 暂存区 Repository: 本地仓库/版本库 Remote: 远程仓库 当在Remote(如Github)上面c ...
- 听H3絮叨:何以让天下没有难用的流程
最近朋友圈.网站新闻铺天盖地是"让天下没有难用的流程",有人就要问了,H3 BPM何德何能,为BPM站台,让天下没有难用的流程? 这是一个关于"办公室空想"的故 ...
- 说说BPM数据表和日志表中几个状态字段的详细解释
有个客户说需要根据这些字段的值作为判断条件做一些定制化需求,所以需要知道这些字段的名词解释,以及里面存储的值具体代表什么意思 我只好为你们整理奉上这些了! Open Work Sheet 0 Sav ...
- Hibernatel框架基础使用
Hibernatel框架基础使用 1.简介 1.1.Hibernate框架由来 Struts:基于MVC模式的应用层框架技术 Hibernate:基于持久层的框架(数据访问层使用)! Spring:创 ...
- 个人也能申请微信小程序获得APPID和手机测试效果
微信小程序昨晚火爆公测,我也第一时间注册了小程序账号开启公测之旅. 注册过程可以看文档:https://my.oschina.net/imhoodoo/blog/780901 进入后台之后我们其实主要 ...
- .NET跨平台:在Ubuntu上用自己编译的dnx运行ASP.NET 5示例程序
在 Linux Ubuntu 上成功编译 dnx 之后,会在 artifacts/build/ 文件夹中生成 dnx-coreclr-linux-x64/ 与 dnx-mono/ 这2个文件夹,前者是 ...
- K-近邻算法(KNN)
简介 k近邻算法是数据分类一种常用的算法,属于监督学习算法的一类,它采用不同特征值之的距离进行分类.K近邻算法具有精度高.对异常值不敏感.无数据输入假定的优点,缺点是计算复杂度高.空间复杂度高.适用于 ...