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语句, ...
随机推荐
- JavaScript权威指南 - 函数
函数本身就是一段JavaScript代码,定义一次但可能被调用任意次.如果函数挂载在一个对象上,作为对象的一个属性,通常这种函数被称作对象的方法.用于初始化一个新创建的对象的函数被称作构造函数. 相对 ...
- 操作系统篇-调用门与特权级(CPL、DPL和RPL)
|| 版权声明:本文为博主原创文章,未经博主允许不得转载. 一.前言 在前两篇文章(<操作系统篇-浅谈实模式与保护模式>和<操作系统篇-分段机制与GDT|LDT>)中,我们提到 ...
- 通俗易懂的来讲讲DOM
DOM是所有前端开发每天打交道的东西,但是随着jQuery等库的出现,大大简化了DOM操作,导致大家慢慢的“遗忘”了它的本来面貌.不过,要想深入学习前端知识,对DOM的了解是不可或缺的,所以本文力图系 ...
- 快速搭建springmvc+spring data jpa工程
一.前言 这里简单讲述一下如何快速使用springmvc和spring data jpa搭建后台开发工程,并提供了一个简单的demo作为参考. 二.创建maven工程 http://www.cnblo ...
- iOS开发之ReactiveCocoa下的MVVM(干货分享)
最近工作比较忙,但还是出来更新博客了,今天给大家分享一些ReactiveCocoa以及MVVM的一些东西,干活还是比较足的.在之前发表过一篇博文,名字叫做<iOS开发之浅谈MVVM的架构设计与团 ...
- spring remoting源码分析--Hessian分析
1. Caucho 1.1 概况 spring-remoting代码的情况如下: 本节近分析caucho模块. 1.2 分类 其中以hession为例,Hessian远程服务调用过程: Hessian ...
- Conversion to Dalvik format failed: Unable to execute dex: Multiple dex files define ...
Conversion to Dalvik format failed: Unable to execute dex: Multiple dex files define ... 这个错误是因为有两个相 ...
- 使用Jenkins配置Git+Maven的自动化构建
Jenkins是一个开源的持续集成工具,应用Jenkins搭建持续集成环境,可以进行自动构建.自动编译和部署,非常方便. 在服务器比较少的情况下,Jenkins的优势并不明显,但是随着项目发展,服务器 ...
- 三大框架SSH整合
三大框架SSH整合 -------------------------------Spring整合Hibernate------------------------------- 一.为什么要整合Hi ...
- mono for android 读取网络远程图片
布局 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android=& ...