最近一直急着在负责弄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去做这个事情。

如下面代码,仅供参考:

 1 /// <summary>
2 /// 基本验证Attribtue,用以WebApi请求的权限处理
3 /// </summary>
4 public class BasicAuthenticationAttribute : ActionFilterAttribute
5 {
6 private static Uni2uni.Framework.Cache.ICache cache = CacheFactory.Redis(RedisDb.User);
7
8 /// <summary>
9 /// 检查用户是否有该WebApi请求执行的权限
10 /// </summary>
11 /// <param name="actionContext"></param>
12 public override void OnActionExecuting(HttpActionContext actionContext)
13 {
14 if (actionContext.Request.Headers.Contains("Set-Cookie"))
15 {
16 var accessToken = actionContext.Request.Headers.GetValues("Set-Cookie");
17 Dictionary<string, string> item = new Dictionary<string, string>();
18 accessToken.FirstOrDefault().ToString().Split('&').Each(i =>
19 {
20 var itemLine = i.Split('=');
21 item.Add(itemLine[0], itemLine[1]);
22 });
23 //解密用户token值,看有没有登录
24 string tokenValue = System.Web.HttpUtility.UrlDecode(item["access_token"]);
25 if (ValidateToken(tokenValue))
26 {
27 base.OnActionExecuting(actionContext);
28 }
29 else
30 {
31 actionContext.Response = new HttpResponseMessage(HttpStatusCode.Unauthorized);
32 actionContext.Response.Content = new StringContent("The request has no token or toke id expired,is invalid !",
33 Encoding.UTF8, "text/plain");
34 }
35 }
36 else
37 {
38 //检查web.config配置是否要求权限校验
39 bool isRquired = (WebConfigurationManager.AppSettings["WebApiAuthenticatedFlag"].ToString() == "true");
40 if (isRquired)
41 {
42 //如果请求Header不包含token,则判断是否是匿名调用
43 var attr = actionContext.ActionDescriptor.GetCustomAttributes<AllowAnonymousAttribute>().OfType<AllowAnonymousAttribute>();
44 bool isAnonymous = attr.Any(a => a is AllowAnonymousAttribute);
45
46 //是匿名用户,则继续执行;非匿名用户,抛出“未授权访问”信息
47 if (isAnonymous)
48 {
49 base.OnActionExecuting(actionContext);
50 }
51 else
52 {
53 actionContext.Response = new HttpResponseMessage(HttpStatusCode.Unauthorized);
54 actionContext.Response.Content = new StringContent("The request is Unauthorized,is nto allow!",
55 Encoding.UTF8, "text/plain");
56 }
57 }
58 else
59 {
60 base.OnActionExecuting(actionContext);
61 }
62 }
63 }
64
65 /// <summary>
66 /// 验证是否登录授权
67 /// </summary>
68 /// <param name="token"></param>
69 /// <returns></returns>
70 public bool ValidateToken(string token)
71 {
72 if (!string.IsNullOrEmpty(token))
73 {
74 var model = cache.Get<LoginMember>(token);
75 Logger.Error("2:请求中的。。。:model:" + model == null ? "不存在" : model.UserName);
76 return model != null ? true : false;
77 }
78 return false;
79 }
80 }

==》【 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 , 简单的( 通用上传 以及 通用分页 )】

仅供参考代码,如下:

   [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 = 6) 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"] = 1;
hash["errmsg"] = "上传出错";
var file = provider.FileData[0];//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 = 10000000;
if (fileinfo.Length <= 0)
{
hash["error"] = 1;
hash["errmsg"] = "请选择上传文件。";
}
else if (fileinfo.Length > maxSize)
{
hash["error"] = 1;
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(1).ToLower()) == -1)
{
hash["error"] = 1;
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"] = 0;
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
}

Web Api 与 Andriod 接口对接开发经验的更多相关文章

  1. Asp.Net Web Api 与 Andriod 接口对接开发经验,给小伙伴分享一下!

    最近一直急着在负责弄Asp.Net Web Api 与 Andriod 接口开发的对接工作! 刚听说要用Asp.Net Web Api去跟 Andriod 那端做接口对接工作,自己也是第一次接触Web ...

  2. Asp.Net Web Api 与 Andriod 接口对接开发

    Asp.Net Web Api 与 Andriod 接口对接开发经验,给小伙伴分享一下!   最近一直急着在负责弄Asp.Net Web Api 与 Andriod 接口开发的对接工作! 刚听说要用A ...

  3. Redis总结(五)缓存雪崩和缓存穿透等问题 Web API系列(三)统一异常处理 C#总结(一)AutoResetEvent的使用介绍(用AutoResetEvent实现同步) C#总结(二)事件Event 介绍总结 C#总结(三)DataGridView增加全选列 Web API系列(二)接口安全和参数校验 RabbitMQ学习系列(六): RabbitMQ 高可用集群

    Redis总结(五)缓存雪崩和缓存穿透等问题   前面讲过一些redis 缓存的使用和数据持久化.感兴趣的朋友可以看看之前的文章,http://www.cnblogs.com/zhangweizhon ...

  4. Web API系列(二)接口安全和参数校验

    以前简单介绍过web api 的设计,但是还是有很多朋友问我,如何合理的设计和实现web api.比如,接口安全,异常处理,统一数据返回等问题.所以有必要系统的总结总结 web api 的设计和实现. ...

  5. Web API 自动生成接口文档

    1.添加NuGet程序包 Microsoft ASP.NET Web API 2.2 Help Page      (这是微软官方的) A Simple Test Client for ASP.NET ...

  6. Web API后端调用接口 (Get,POST,Put,Delete)

    using System; using System.Collections; using System.Collections.Generic; using System.IO; using Sys ...

  7. 使用RAP2和Mock.JS实现Web API接口的数据模拟和测试

    最近一直在思考如何对Web API的其接口数据进行独立开发的问题,随着Web API的越来越广泛应用,很多开发也要求前端后端分离,例如统一的Web API接口后,Winform团队.Web前端团队.微 ...

  8. Winform混合式开发框架访问Web API接口的处理

    在我的混合式开发框架里面,集成了WebAPI的访问,这种访问方式不仅可以实现简便的数据交换,而且可以在多种平台上进行接入,如Winform程序.Web网站.移动端APP等多种接入方式,Web API的 ...

  9. Web API系列(三)统一异常处理

    前面讲了webapi的安全验证和参数安全,不清楚的朋友,可以看看前面的文章,<Web API系列(二)接口安全和参数校验>,本文主要介绍Web API异常结果的处理.作为内部或者是对外提供 ...

随机推荐

  1. MFC 静态文本的自绘 空心字的实现

    想在对话框里,显示几个字是很简单的,只要用静态文本的输出就可以了.然而有时候我们需要显示特效的字,我们希望显示的文字就像Word里的艺术字一样,看起来美观.这时我们可以重写CStatic类.用Draw ...

  2. mysql 慢查询的小结

    MySQL优化的第一步应该做的就是排查问题,找出瓶颈,而通常情况下的瓶颈和问题都需要通过观察MySQL的运行情况来进行分析,而对于大多数的程序员来说,最容易发现并解决的问题就是MySQL的慢查询或者没 ...

  3. XmlValidationHelper XSD、Schema(XmlSchemaSet)、XmlReader(XmlValidationSettings)、XmlDocument、XDocument Validate

    namespace Test { using Microshaoft; using System; using System.Xml; using System.Xml.Linq; class Pro ...

  4. Spring 自带的定时任务

    需要几天后,或者某个时间后,定时查询数据.需要用到Spring自带的一个注解 @Scheduled(cron="0/5 * * * * ? ")//每隔5秒钟执行 创建一个clas ...

  5. html 超文本标记语言

    1.html超文本标记语言 2.在html中存在着大量的标签,我们用html中存在的标签将要显示在网页的内容包含起来. 3.css 控制网页显示内容的效果. 4.html+css 只能是静态网页. 5 ...

  6. 分布式平台Spark环境的搭建

    1.安装Spark之前需要先安装Java,Scala及Python(个人喜欢用pyspark,当然你也可以用原生的Scala) 首先安装Java jdk: 我们可以在Oracle的官网下载Java S ...

  7. java中注解的使用与实例(一)

    注解目前非常的流行,很多主流框架都支持注解,而且自己编写代码的时候也会尽量的去用注解,一时方便,而是代码更加简洁. 注解的语法比较简单,除了@符号的使用之外,它基本与Java固有语法一致.Java S ...

  8. 16-1-27---JDBC复习(01)

    JDBC数据库连接学习    用jdbc连接数据库    1.加载驱动        Class.forName("");        用注册的方式会使内存中存在两个对象,而用上 ...

  9. 织梦cms更新新建的栏目提示:DedeTag Engine Create File False:C:/phpStudy/WWW/

    这个问题怎么解决呢?只是更换了一下栏目名称.增加了新的栏目,结果就不行了. 问题原因: 新建的栏目没有"列表命名规则",导致cms解析的时候,出现解析错误. 解决办法 在下图填入: ...

  10. Ajax浅学习

    写在前面:响应事件 function addEvent(obj, type, fn) { if (obj.addEventListener) { obj.addEventListener(type, ...