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语句, ...
随机推荐
- PHP-生成缩略图和添加水印图-学习笔记
1.开始 在网站上传图片过程,经常用到缩略图功能.这里我自己写了一个图片处理的Image类,能生成缩略图,并且可以添加水印图. 2.如何生成缩略图 生成缩略图,关键的是如何计算缩放比率. 这里,我根据 ...
- Tcp/ip 报文解析
在编写网络程序时,常使用TCP协议.那么一个tcp包到底由哪些东西构成的呢?其实一个TCP包,首先需要通过IP协议承载,而IP报文,又需要通过以太网传送.下面我们来看看几种协议头的构成 一 .Ethe ...
- 一看就懂的ReactJs入门教程-精华版
现在最热门的前端框架有AngularJS.React.Bootstrap等.自从接触了ReactJS,ReactJs的虚拟DOM(Virtual DOM)和组件化的开发深深的吸引了我,下面来跟我一起领 ...
- Mysql事务探索及其在Django中的实践(一)
前言 很早就有想开始写博客的想法,一方面是对自己近期所学知识的一些总结.沉淀,方便以后对过去的知识进行梳理.追溯,一方面也希望能通过博客来认识更多相同技术圈的朋友.所幸近期通过了博客园的申请,那么今天 ...
- 23种设计模式--中介者模式-Mediator Pattern
一.中介者模式的介绍 中介者模式第一下想到的就是中介,房子中介,婚姻中介啊等等,当然笔者也希望来个婚姻中介给我介绍一个哈哈哈,,回归正题中介者模式分成中介者类和用户类,根据接口编程的方式我们再 ...
- LeetCode 7. Reverse Integer
Reverse digits of an integer. Example1: x = 123, return 321 Example2: x = -123, return -321 Have you ...
- .net 大型分布式电子商务架构说明
.net大型分布式电子商务架构说明 背景 构建具备高可用,高扩展性,高性能,能承载高并发,大流量的分布式电子商务平台,支持用户,订单,采购,物流,配送,财务等多个项目的协作,便于后续运营报表,分析,便 ...
- PHP 获取 特定时间范围 类
目录 前序 用途 功能及事项 使用方法 代码及注释 前序: 总体来说,我更应该是一个 android 移动开发者,而不是一个 phper,如果说只做移动端的 APP ,我也不会学这么多,这 2年来, ...
- SDWebImage源码解读 之 UIImage+GIF
第二篇 前言 本篇是和GIF相关的一个UIImage的分类.主要提供了三个方法: + (UIImage *)sd_animatedGIFNamed:(NSString *)name ----- 根据名 ...
- Struts2入门(六)——国际化
一.前言 1.1.国际化简介 国际化是指应用程序在运行的时候,根据客户端请求来自的国家地区.语言的不同而显示不同的界面(简单说就是根据你的地区显示相关地区的语言,如果你现在在英国,那么显示的语言就是英 ...