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语句, ...
随机推荐
- 深入理解JS 执行细节
javascript从定义到执行,JS引擎在实现层做了很多初始化工作,因此在学习JS引擎工作机制之前,我们需要引入几个相关的概念:执行环境栈.全局对象.执行环境.变量对象.活动对象.作用域和作用域链等 ...
- 8.仿阿里云虚拟云服务器的FTP(包括FTP文件夹大小限制)
平台之大势何人能挡? 带着你的Net飞奔吧!:http://www.cnblogs.com/dunitian/p/4822808.html#iis 原文:http://dnt.dkill.net/Ar ...
- MVC5 网站开发之九 网站设置
网站配置一般用来保存网站的一些设置,写在配置文件中比写在数据库中要合适一下,因为配置文件本身带有缓存,随网站启动读入缓存中,速度更快,而保存在数据库中要单独为一条记录创建一个表,结构不够清晰,而且读写 ...
- [C#] 进阶 - LINQ 标准查询操作概述
LINQ 标准查询操作概述 序 “标准查询运算符”是组成语言集成查询 (LINQ) 模式的方法.大多数这些方法都在序列上运行,其中的序列是一个对象,其类型实现了IEnumerable<T> ...
- pt-online-schema-change中update触发器的bug
pt-online-schema-change在对表进行表结构变更时,会创建三个触发器. 如下文测试案例中的t2表,表结构如下: mysql> show create table t2\G . ...
- 【知识必备】一文让你搞懂design设计的CoordinatorLayout和AppbarLayout联动,让Design设计更简单~
一.写在前面 其实博主在之前已经对design包的各个控件都做了博文说明,无奈个人觉得理解不够深入,所以有了这篇更加深入的介绍,希望各位看官拍砖~ 二.从是什么开始 1.首先我们得知道Coordina ...
- 易用BPM时代,软件开发者缘何选择H3?
近年来,企业级软件开发市场暗流汹涌,呈现出多种态势.软件开发团队规模趋于小型化,工作方式趋于快捷化,超过半数的软件开发者在工作中会选择使用易用的软件开发工具.随着流程管理越来越受到企业的重视,流程开发 ...
- Visual Studio 2013 添加一般应用程序(.ashx)文件到SharePoint项目
默认,在用vs2013开发SharePoint项目时,vs没有提供一般应用程序(.ashx)的项目模板,本文解决此问题. 以管理员身份启动vs2013,创建一个"SharePoint 201 ...
- Spark的StandAlone模式原理和安装、Spark-on-YARN的理解
Spark是一个内存迭代式运算框架,通过RDD来描述数据从哪里来,数据用那个算子计算,计算完的数据保存到哪里,RDD之间的依赖关系.他只是一个运算框架,和storm一样只做运算,不做存储. Spark ...
- FineReport如何部署Tomcat服务器集群
环境准备 Tomcat服务器集群中需要进行环境准备: Apache:Apache是http服务器,利用其对Tomcat进行负载均衡,这里使用的版本是Apache HTTP Server2.0.64: ...