Asp.Net Web Api 与 Andriod 接口对接开发经验,给小伙伴分享一下!
最近一直急着在负责弄Asp.Net Web Api 与 Andriod 接口开发的对接工作!
刚听说要用Asp.Net Web Api去跟 Andriod 那端做接口对接工作,自己也是第一次接触Web Api,我就开始了边学习边开发,甚至连自己都没有来得急去理解和消化一些知识,就得去做项目了,感觉还是挺赶,挺忙的,很多东西都是在地铁上学习到的,很感谢 ( Artech 和 张善友 )大神的博文 给予的帮助与启发 。
项目目录如下:
由于我这里所做的web api提供的是一整套项目接口,很多 api 接口都需要登录授权的,也有部分是匿名的。
==》 对于 对外开发 的 web api 接口,可能都具有 “匿名访问” 或者 是 "CORS授权机制",或者是还要去限制 web api 调用的频率。
【CORS授权机制-知识】:http://www.cnblogs.com/artech/tag/ASP.NET Web API
【限制 Web Api 访问频率】:http://www.cnblogs.com/shanyou/p/3194802.html
对于哪些web api 需要 匿名开发,哪些需要登录授权才能访问,大家可以做一个通用的Attribute去做这个事情。
如下面代码,仅供参考:
aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAV4AAAArCAIAAAC/0XeLAAAFB0lEQVR4nO2dPU/bQBjH+zkYPCBRiXhkYK3oclKHrvABKrHhj4CqKhJBoqpOiI5UFDFVmSIBA6pqqSNL46Ht1DDBEtrh5g4m53t5zvbFAZzj/5OFyPnlXuz7+fEFH8/G43/j8T8BAAAKz6AGAIDNU1FDt9td03nsEgHQap6EGrrd7tu3727Hf+UCNQBQTphqMAIE6YX8o4caMs4ixjMhxCCJksH9lhqAFjEHahgOh7675P2/ZHGoIeMsKmA8gxrAU6XtakjTtNPp+O7VRA0OAUg1lGwDQDi0Wg1pmi4tLUVR5Lsj1ABAQ9qrBukFLzWsVeGnhiIhV8MgUR837tL1hLt9BomSBMDc0VI1qF7wUsPW1la5Gs7PzmuONTCeWWoQuj4GSdH7ZXp+EAQWYL5poxoML3ip4eTkpFwNe3vvG0QN+jZKDKEEDnjiACHQOjUMh8NOp2N0Oa/dy9Wwvr4+SzUQjwxQAwiB1qmhORsbG+V2+PXz92zUIAaJ8uQwSDBOCcIhQDXYfxNtcHR01EANkwGJPF5QRicmO0INIAQCVMPFxUW5GnIeu5gAtJoA1QAAaA7UAAAggBoAAARQAwCAAGoAABBADQAAAqgBAEAQjhrSNH3sIgAQDuGoYXl5eS7tUEwkNUPotzumoUnx7qVq9TPFn6U2Ihw1RFEUx3FDO+ye7qz2VvLl4Ou+EGK1tyJ/utDewPTtC9X9J+PM9yXvANQwRa2NTKGGRgSlhn6/X2mH48vR88+jhcPR88+j48uRuir3wuuPrw6+7u+e7vQvv0hN5IvrmGpH1N64mgkZZ4zVuMhdE0lMl+XUlZhRhyRqrR65Ti5eJYFHTIJSgxCi0g4Lh6Ptb1dnP/5sf7taONTUsNpbefnhxc34xkgUNaIGe0aXWZFxxnhWY9baoNRA1RpqeFBCU4MQotfrxXF8fX3te4TV3srm8RsjxTNq0K8w4r1MK03bg5xOjvHMrZ+7342Z6QZJxDhPzLyJ42tbTnJSNiovnlmZWvtqL7KbuctaGbVWj8yYmosx416RqZKu5lrdemRDGSdcW0ud57knNDWkaRrHcb/fd222cDhSF3VVk6ghMq8tIUTGE+sxw745ae99Wxei1jco/5g9QSlRkSzny7ftQm6pHKqseFQF6+xbbEzm7qi1M2rQZ9zTGyTSmsQ6Bc7WK4kCrXYINOAISg2VXhATNdyO/9pq2Dx+o441HH3/VDNrLXzXBxus+0muEf0GKTupdYcyRjGUe7XXxW1GA3qMYG1Jdm/HM4pVwTr7kitk7o5al6pBb3G7QZSPla1HNxR1SookR3gxzwSlhkoviFI13Ixvcjvky5RqkJ8yziKqM08+m1NJOq85lenue5YE6LJ7qoGuYE01kIGMTKRq/ZBqKOnmzrXKOQ2CcNSwuLhY6QVR+kAxNXTUYNzvJr2aG1elHnXLvs15Zn3bMfmsxN7KV3xVaqCnq6utBrJ4dgVrPlDQzwsyuqFqPZUa9KcOeZjK1rMaSnsu09vBPqdBEI4a6njhntBvc/LaKGJtliREuErfC4t19vegWi+xjnyXKIchrUCdGi6jtywO5S6eq4L0viXDkHru1bUuYjLzPwLo7ZlxFiWJOQpZo/WohlKHQsx2sM5pEISjBgDADIEaAAAEUAMAgABqAAAQQA0AAAKoAQBAADUAAAigBgAAQThqmMspngBoK+GoYV4ngJs55AuUAHjyH6sXepPAYsCFAAAAAElFTkSuQmCC" alt="" />
/// <summary>
/// 基本验证Attribtue,用以WebApi请求的权限处理
/// </summary>
public class BasicAuthenticationAttribute : ActionFilterAttribute
{
private static Uni2uni.Framework.Cache.ICache cache = CacheFactory.Redis(RedisDb.User); /// <summary>
/// 检查用户是否有该WebApi请求执行的权限
/// </summary>
/// <param name="actionContext"></param>
public override void OnActionExecuting(HttpActionContext actionContext)
{
if (actionContext.Request.Headers.Contains("Set-Cookie"))
{
var accessToken = actionContext.Request.Headers.GetValues("Set-Cookie");
Dictionary<string, string> item = new Dictionary<string, string>();
accessToken.FirstOrDefault().ToString().Split('&').Each(i =>
{
var itemLine = i.Split('=');
item.Add(itemLine[], itemLine[]);
});
//解密用户token值,看有没有登录
string tokenValue = System.Web.HttpUtility.UrlDecode(item["access_token"]);
if (ValidateToken(tokenValue))
{
base.OnActionExecuting(actionContext);
}
else
{
actionContext.Response = new HttpResponseMessage(HttpStatusCode.Unauthorized);
actionContext.Response.Content = new StringContent("The request has no token or toke id expired,is invalid !",
Encoding.UTF8, "text/plain");
}
}
else
{
//检查web.config配置是否要求权限校验
bool isRquired = (WebConfigurationManager.AppSettings["WebApiAuthenticatedFlag"].ToString() == "true");
if (isRquired)
{
//如果请求Header不包含token,则判断是否是匿名调用
var attr = actionContext.ActionDescriptor.GetCustomAttributes<AllowAnonymousAttribute>().OfType<AllowAnonymousAttribute>();
bool isAnonymous = attr.Any(a => a is AllowAnonymousAttribute); //是匿名用户,则继续执行;非匿名用户,抛出“未授权访问”信息
if (isAnonymous)
{
base.OnActionExecuting(actionContext);
}
else
{
actionContext.Response = new HttpResponseMessage(HttpStatusCode.Unauthorized);
actionContext.Response.Content = new StringContent("The request is Unauthorized,is nto allow!",
Encoding.UTF8, "text/plain");
}
}
else
{
base.OnActionExecuting(actionContext);
}
}
} /// <summary>
/// 验证是否登录授权
/// </summary>
/// <param name="token"></param>
/// <returns></returns>
public bool ValidateToken(string token)
{
if (!string.IsNullOrEmpty(token))
{
var model = cache.Get<LoginMember>(token);
Logger.Error("2:请求中的。。。:model:" + model == null ? "不存在" : model.UserName);
return model != null ? true : false;
}
return false;
}
}
==》【 OData 】
考虑到手机项目的限制,在针对(查询分页,查询筛选,排序)方面,我用了Asp.Net Web Api OData,由于咋们的项目架构只支持.Net 4.0,最新的已经到 Asp.Net Web Api 2 OData了。
OData相关知识链接:
http://www.cnblogs.com/Kummy/p/3486097.html
http://www.cnblogs.com/shanyou/archive/2013/06/11/3131583.html
==》【 Web Api Post [FromBody] 支持简单的数据类型。】
在Web Api 开发中,我们会发现一个问题, Post 已经不支持简单的数据类型了。
如下面例子:
[AllowAnonymous]
[HttpPost]
public string Test([FromBody]string Name)
{
return null;
}
我们会发现,这个Post过来的类型怎么都是null
于是我找了很久,发现了解决这个问题的办法。
地址: http://weblog.west-wind.com/posts/2012/Sep/11/Passing-multiple-simple-POST-Values-to-ASPNET-Web-API
==》【 Web Api , 简单的( 通用上传 以及 通用分页 )】
aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAARgAAAAcCAIAAAA1Cjd5AAADK0lEQVR4nO2bu27bMBSG8xweNGQIYGj04LVAFwId+hQBMvIRskaZCiJIRxeNx0CTgHQLIqCjl4IPUGWyF7cL5w60KN50sU2HbfV/EAJbl0MaOJ/OoRyfCQDA0ZzFngAA/wMQCYAAQCQAAgCRAAgARAIgABAJgADEEaksyyjjAnAi4og0nU7/DZc4IwlhPOIMCprQwngB/kbiiJQkSZqmR7p0+3Qzz2Zyu3++E0LMs5n62wlnJBmUlrZIBU1q3iirDxRJm2gS+VYwDqKJlOd5r0vLVXXxUE0W1cVDtVxV+iFp0cfPH+6f726fbvLVo5JKbl3Dc0YIIfuqUFBDn4Lun5+cHTLqgSKp6RX0zbQfL9FEEkL0ujRZVNcvr99+/Lx+eZ0sDJHm2ez9p3eb7cbaKQZUJM4IYXzPVilINsYR6YBRwb7EFEkIkWVZmqbr9XrfCPNsdrW8tPYMq0jSIzPXdsnWNES7xFM5aJxsobdRKmELmhDGqNZbaacRxvURd5Hb4rgiNWfWk7KjafM1PeKMOGP49rlD+D+yPOqLMC5iilSWZZqmeZ63nTZZVPqmHzq8IjUpZt+1myRQ5adfpILqqdbULa0RbBZaek6bI3bFcV+4xcaK1rZG4ow6DZ+nYHXXM3Oq/gijI5pIvRaJWqRf29+uSFfLS32N9PX7l4FDW4sH/21bve0Vyd7vvaCugY5IRuK3xjFFMhRRmti5bMQz21KnesiI2vD+Idqm6oswPmI+teu2SHSKtNlupEtyGyySkyNa1egSqc0kjwDy/fEiqTiOSJ6JdIqk3nFGVL7bV0i/3Ka39yP7IoyPOCKdn5/3WiQ6W7sDsR8ZGP2N2XXZbY+ehPJStfIx7v3+vrFPpK44bmund4TeG0FLRbJKcP0ZmT0l3xBNg6ofLRjjvgijI45IQyw6Be6jt3oPZySh1H7W4Mt2d1Hd/rDBFqluq5qHDfZcfHEskbxLe49ITtU1riSUqiucZyy+IfSv1Jqj7RFGBv7XTjLeWykIAkSSQCRwFBBJApHAUUAkAAIAkQAIAEQCIAAQCYAAQCQAAoCfmgMQAPzUHJyOEf1O/g9pw70Igde0kgAAAABJRU5ErkJggg==" alt="" />
仅供参考代码,如下:
[BasicAuthentication]
public abstract class ApiControllerBase : ApiController
{
#region Common Pager
/// <summary>
/// 给结果集扩展一个分页
/// </summary>
/// <typeparam name="T">实体</typeparam>
/// <param name="_defaultSetting">页面设置</param>
/// <param name="options">筛选条件集合</param>
/// <param name="_list">待分页集合</param>
/// <returns></returns>
public PageResult<TEntity> GetPager<TEntity>(ODataQueryOptions<TEntity> options, IEnumerable<TEntity> _list, int PageSizeCount = ) where TEntity : class
{
ODataQuerySettings settings = new ODataQuerySettings
{
PageSize = PageSizeCount
};
IQueryable results = options.ApplyTo(_list.AsQueryable(), settings);
Request.GetInlineCount();
return new PageResult<TEntity>(
results as IEnumerable<TEntity>,
Request.GetNextPageLink(),
Request.GetInlineCount());
}
#endregion #region Common Upload
/// <summary>
/// 通用上传图片-操作
/// </summary>
/// <typeparam name="T">上传实体</typeparam>
/// <param name="dirPath">上传路劲</param>
/// <param name="fileNameAction">文件名自定义扩展</param>
/// <param name="Entity">实体名字</param>
/// <returns>图片上传是否成功</returns>
[NonAction]
public Hashtable CommonUpload<T>(string dirPath, Action<string> fileNameAction, out T Entity) where T : class
{
var queryp = Request.GetQueryNameValuePairs(); //获得查询字符串的键值集合
Entity = GetUploadEntity<T>(queryp); //实体赋值操作 // 检查是否是 multipart/form-data
if (!Request.Content.IsMimeMultipartContent("form-data"))
throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
//文件保存目录路径
string SaveTempPath = dirPath;
String dirTempPath = HttpContext.Current.Server.MapPath(SaveTempPath);
Logger.Error("文件路径:" + dirTempPath);
// 设置上传目录
var provider = new MultipartFormDataStreamProvider(dirTempPath); //Logger.Error("queryp参数:" + param);
var task = Request.Content.ReadAsMultipartAsync(provider).
ContinueWith<Hashtable>(o =>
{
Hashtable hash = new Hashtable();
hash["error"] = ;
hash["errmsg"] = "上传出错";
var file = provider.FileData[];//provider.FormData
string orfilename = file.Headers.ContentDisposition.FileName.TrimStart('"').TrimEnd('"');
FileInfo fileinfo = new FileInfo(file.LocalFileName); Logger.Error("最大文件大小:" + fileinfo.Length);
Logger.Error("最大格式:" + orfilename);
//最大文件大小
int maxSize = ;
if (fileinfo.Length <= )
{
hash["error"] = ;
hash["errmsg"] = "请选择上传文件。";
}
else if (fileinfo.Length > maxSize)
{
hash["error"] = ;
hash["errmsg"] = "上传文件大小超过限制。";
}
else
{
string fileExt = orfilename.Substring(orfilename.LastIndexOf('.'));
//定义允许上传的文件扩展名
String fileTypes = "gif,jpg,jpeg,png,bmp";
if (String.IsNullOrEmpty(fileExt) || Array.IndexOf(fileTypes.Split(','), fileExt.Substring().ToLower()) == -)
{
hash["error"] = ;
hash["errmsg"] = "上传文件扩展名是不允许的扩展名。";
}
else
{
//String ymd = DateTime.Now.ToString("yyyyMMdd", System.Globalization.DateTimeFormatInfo.InvariantInfo);
//String newFileName = DateTime.Now.ToString("yyyyMMddHHmmss_ffff", System.Globalization.DateTimeFormatInfo.InvariantInfo);
//String finalFileName = newFileName + fileExt;
string excute_FileName = string.Empty;
fileNameAction = (i) => { excute_FileName = i; };
fileinfo.CopyTo(Path.Combine(dirTempPath, excute_FileName), true);
fileinfo.Delete();
hash["error"] = ;
hash["errmsg"] = "上传成功";
hash["filePathUrl"] = excute_FileName;
}
}
return hash;
});
return null;
} /// <summary>
/// 反射动态的实体赋值-操作
/// </summary>
/// <typeparam name="Entity"></typeparam>
/// <param name="queryp"></param>
/// <returns></returns>
[NonAction]
public Entity GetUploadEntity<Entity>(IEnumerable<KeyValuePair<string, string>> queryp) where Entity : class
{
var entity = typeof(Entity);
Object model = entity.Assembly.CreateInstance(entity.FullName, true);
var props = entity.GetProperties(BindingFlags.Instance | BindingFlags.Public);
foreach (PropertyInfo propertyInfo in typeof(Entity).GetProperties())
{
queryp.Each(i =>
{
if (i.Key.Equals(propertyInfo.Name.ToString()))
{
propertyInfo.SetValue(model, i.Value, null);
}
});
}
return (Entity)model;
}
#endregion
}
希望,能对各位小伙伴不吝赐教。
祝各位小伙伴,元旦节快乐!
Asp.Net Web Api 与 Andriod 接口对接开发经验,给小伙伴分享一下!的更多相关文章
- Asp.Net Web Api 与 Andriod 接口对接开发
Asp.Net Web Api 与 Andriod 接口对接开发经验,给小伙伴分享一下! 最近一直急着在负责弄Asp.Net Web Api 与 Andriod 接口开发的对接工作! 刚听说要用A ...
- Web Api 与 Andriod 接口对接开发经验
最近一直急着在负责弄Asp.Net Web Api 与 Andriod 接口开发的对接工作! 刚听说要用Asp.Net Web Api去跟 Andriod 那端做接口对接工作,自己也是第一次接触Web ...
- 旅图beta版 asp.net web api 单元测试
旅图 beta版 asp.net web api 单元测试 测试接口:http://120.27.7.115:1010/Help 测试目的 对每个接口单元进行测试,保证每个接口的可靠性. 单元描述 注 ...
- 购物车Demo,前端使用AngularJS,后端使用ASP.NET Web API(3)--Idetity,OWIN前后端验证
原文:购物车Demo,前端使用AngularJS,后端使用ASP.NET Web API(3)--Idetity,OWIN前后端验证 chsakell分享了前端使用AngularJS,后端使用ASP. ...
- 使用ASP.NET Web API Help Pages 创建在线接口文档
操作步骤 1.新建Web API项目 2.在项目Areas文件夹下找到以下文件,取消注释图中代码. 3.右键解决方案,属性,如图设置. 4.运行程序,点击右上角API 接口列表: 详情-无参数: 详情 ...
- ASP.NET Web API 接口执行时间监控
软件产品常常会出现这样的情况:产品性能因某些无法预料的瓶颈而受到干扰,导致程序的处理效率降低,性能得不到充分的发挥.如何快速有效地找到软件产品的性能瓶颈,则是我们感兴趣的内容之一. 在本文中,我将解释 ...
- Asp.Net Web Api 接口,拥抱支持跨域访问。
如何让你的 Asp.Net Web Api 接口,拥抱支持跨域访问. 由于 web api 项目通常是被做成了一个独立站点,来提供数据,在做web api 项目的时候,不免前端会遇到跨域访问接口的问题 ...
- Asp.Net Web Api 接口
如何让你的 Asp.Net Web Api 接口,拥抱支持跨域访问. 由于 web api 项目通常是被做成了一个独立站点,来提供数据,在做web api 项目的时候,不免前端会遇到跨域访问接口的 ...
- ASP.NET Web API 入门 (API接口、寄宿方式、HttpClient调用)
一.ASP.NET Web API接口定义 ASP.NET Web API默认实现了Action方法和HTTP方法的映射,Action方法方法名体现了其能处理的请求必须采用的HTTP方法 二.寄宿方式 ...
随机推荐
- html+css学习笔记 3[浮动]
inline-block/float(浮动) 回顾:inline-block 特性: 1.块在一排显示 2.内联支持宽高 3.默认内容撑开宽度 4.标签之间的换行间隙被解析(问题) 5.ie ...
- 清橙A1363. 水位 - 清华大学2012年信息学优秀高中学子夏令营
问题描述 有一个正方形的地区,该地区特点鲜明:如果把它等分为N×N个小正方形格子的话,在每个格子内的任意地点的地表高度是相同的,并且是一个0到M之间的整数.正方形地区的外部被无限高的边界包围. 该地区 ...
- [设计模式] 19 观察者模式 Observer Pattern
在GOF的<设计模式:可复用面向对象软件的基础>一书中对观察者模式是这样说的:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新.当一个 ...
- 消除SDK更新时的“https://dl-ssl.google.com refused”异常
原地址:http://blog.csdn.net/x605940745/article/details/17911115 消除SDK更新时的“https://dl-ssl.google.com ref ...
- 趣味Python入门(一):初识Python
[编者按]本文作者是 Abhishek Jaiswal ,擅长 .NET.C#.Python 等多种语言的技术控.本文中,作者通过活泼有趣的口吻向大家介绍了 Python 语言的基础知识,后期多学习历 ...
- pl/sql tutorial
http://plsql-tutorial.com/plsql-procedures.htm What is PL/SQL? PL/SQL stands for Procedural Language ...
- Dijsktra算法C++实现
Dijsktra算法解决了有向图G=(V,E)上带权的单源最短路径问题.但要求所有边的权值非负. 思想:Dijkstra算法中设置了一顶点集合S,从源点s到集合中的顶点的最终最短路径的权值均已确定.算 ...
- POJ 1330 Nearest Common Ancestors(求最近的公共祖先)
题意:给出一棵树,再给出两个节点a.b,求离它们最近的公共祖先.方法一: 先用vector存储某节点的子节点,fa数组存储某节点的父节点,最后找出fa[root]=0的根节点root. 之后 ...
- Asp.net 身份验证
Forms 验证方式对基于用户的验证授权提供了很好的支持,可以通过一个登录页面验证用户的身份,将此用户的身份发回到客户端的Cookie,之后此用户再访问这个 web应用就会连同这个身份Cookie一起 ...
- POJ 1054 The Troublesome Frog(枚举+剪枝)
题目链接 题意 :给你r*c的一块稻田,每个点都种有水稻,青蛙们晚上会从水稻地里穿过并踩倒,确保青蛙的每次跳跃的长度相同,且路线是直线,给出n个青蛙的脚印点问存在大于等于3的最大青蛙走的连续的脚印个数 ...