当前位置:  编程技术>.net/c#/asp.net
本页文章导读:
    ▪HttpLib - 一个对 Http 协议进行封装的库      今日,在 Codeplex 上看到一个开源项目,对 Http 协议进行了封装,这下可以方便这些在 .NET 平台下访问 Web 服务器的同学们了,比如,从 Web 服务器抓取一个页面,使用 .NET 而不是借助浏览器向.........
    ▪Web甘特图开发系列:(五) 权限编辑      在实际项目管理系统应用中,需要根据用户的不同角色、权限,来控制甘特图上可编辑的内容。普加甘特图权可根据权限,精确控制单元格编辑、条形图拖拽、右键菜单功能项等功能显示和操.........
    ▪使Web API支持namespace      问题描述 假设我有一个应用场景:Core Framework可以用于任何区域的站点,其中的CustomersController有个取customer的fullname的方法GetFullName(),可想而知,这个api在中国和美国的站点上,应该得到不同.........

[1]HttpLib - 一个对 Http 协议进行封装的库
    来源:    发布时间: 2013-10-22

今日,在 Codeplex 上看到一个开源项目,对 Http 协议进行了封装,这下可以方便这些在 .NET 平台下访问 Web 服务器的同学们了,比如,从 Web 服务器抓取一个页面,使用 .NET 而不是借助浏览器向服务器发一个 Post 请求之类的操作,就可以直接调用一下实现好的方法了。

项目的地址:http://httplib.codeplex.com/

也可以直接到下载页面下载你需要的源代码或者编译完成的类库。

下载页面的地址:http://httplib.codeplex.com/releases/view/99620

项目比较新,所以下载量看来并不大。

项目的使用说明:

在项目的首页上有一个简短的说明,虽然简单,但是比较使用。

Project 说明

HttpLib  使得在 C# 中异步地访问 Web 服务器上的数据变得更加容易。 库中包含了将文件上传到服务器中以及从服务器下载页面的方法。
这个项目设计用来访问当前已经存在的 Web 服务。如果你计划创建新的包含服务器端和客户端的应用,建议考虑使用 WCF.

支持的 HTTP 方法 

    • GET
    • POST
      • Form Encoded
      • Multipart File Upload
    • PUT
    • HEAD
    • DELETE

示例

首先,在项目中引用 httplib 程序集。

在代码的开头部门,一般先 using 命名空间。

using Redslide.HttpLib

从服务器端获取内容。比如抓取页面。

Request.Get("http://google.com/",
result=>
{
Console.Write(result);
});

向服务器提交信息,使用 Post 方式。提交的参数使用一个对象表示。

Request.Post("http://testing.local/post.php", new {name="james",username="Redslide"},
result=>
{
Console.Write(result);
});

以 Post 方式提交信息,如果出现异常,捕获异常。

Request.Post("http://testing.local/post.php", new { name = "value"},
result=>
{
Console.Write(result);
},
e=>
{
Console.Write(e.ToString());
});

上传文件到服务器,第三个参数是上传文件。

Request.Upload("http://testing.local/post.php", new {name = "value"}, new[] {
new NamedFileStream("file", "photo.jpg", "image/jpeg", new FileStream(@"C:\photo.jpg",FileMode.Open))
},
result=>
{
Console.Write(result);
});

  

本文链接


    
[2]Web甘特图开发系列:(五) 权限编辑
    来源:    发布时间: 2013-10-22

在实际项目管理系统应用中,需要根据用户的不同角色、权限,来控制甘特图上可编辑的内容。

普加甘特图权可根据权限,精确控制单元格编辑、条形图拖拽、右键菜单功能项等功能显示和操作细节。

1.单元格编辑控制

监听"cellbeginedit"事件,在编辑前,判断用户是否可以编辑此单元格,不满足,就取消操作。

//控制单元格是否可编辑
gantt.on("cellbeginedit", function (e) {
var task = e.record, column = e.column, field = e.field;
if (task.Summary == 1) {
e.cancel = true;
}
if (field == 'Duration') {
e.cancel = true;
}
});

 本代码控制摘要任务、工期列不能编辑。

2.条形图拖拽控制

监听"itemdragstart"事件,在拖拽前,判断用户是否可修改任务日期,不满足,就取消操作。

//只允许调整百分比
gantt.on("itemdragstart", function (e) {
if (e.action == "finish" || e.action == "move") { //percentcomplete
e.cancel = true;
}
});

 本代码控制用户不能拖拽开始、不能移动条形图。

3.右键菜单项显示控制

 监听菜单的"beforeopen"事件,如果当前点击的任务跟用户操作权限不匹配,则隐藏、禁用一些菜单项。

//右键菜单
var menu = new GanttMenu();
gantt.setContextMenu(menu);

//监听菜单的opening事件,此事件在菜单显示前激发。可以控制菜单项的显示和可操作。
menu.on("beforeopen", function (e) {
var gantt = this.owner; //PlusProject对象
var task = gantt.getSelected();
if (!task) {
e.cancel = true;
return;
}

//显示和可编辑所有菜单项

this.add.show();
this.edit.show();
this.remove.show();

this.upgrade.enable();
this.downgrade.enable();

if (task.Summary) {
this.edit.hide();
this.remove.hide();

this.upgrade.disable();
this.downgrade.disable();
} else {
this.add.hide();
}
});

 

访问示例请点击这里。

本文链接


    
[3]使Web API支持namespace
    来源:    发布时间: 2013-10-22

问题描述

假设我有一个应用场景:Core Framework可以用于任何区域的站点,其中的CustomersController有个取customer的fullname的方法GetFullName(),可想而知,这个api在中国和美国的站点上,应该得到不同的返回值。如下图所示:

这样的设计可以带来两个好处:

1、利用了OO的思想,可以封装各个区域customer service相关的一些公共逻辑

2、使得client端可以一致的接口访问服务,如:http://hostname/api/customers 

这看上去不错,但是为了达到我的目的,就必须让web api支持在不同的namespace(或者area)中,存在相同名称的controller。但是web api默认情况下是不支持的,那么是否可以通过某种方法,使web api支持这种效果呢?答案是肯定的。

查找原因

为了让web api支持namespace(或者area),就必须找到为什么默认情况下web api不支持,在这个过程中,也许能找到切入点。为了能找到原因,我做了如下工作:

1、Server-Side Handlers

从mvc4官网,找到了server端的request处理过程,如下图所示:

从图中我们可以看到,controller是通过HttpControllerDispatcher调度器,来处理的。

2、HttpControllerDispatcher

HttpControllerDispatcher 位于System.Web.Http.Dispatcher命名空间中,其源代码中有一个私有属性:

private IHttpControllerSelector ControllerSelector
{
get
{
if (this._controllerSelector == null)
{
this._controllerSelector = this._configuration.Services.GetHttpControllerSelector();
}
return this._controllerSelector;
}
}

从代码中可以看出,该属性,只是简单的从services容器中,得到IHttpControllerSelector类型的一个对象,所以问题现在转移到在这个controllerselector对象上。

3、DefaultHttpControllerSelector

在this._configuration.Services.GetHttpControllerSelector();这条语句中,_configuration其实就是System.Web.Http.HttpConfiguration,在其构造函数中,可以看到:

this.Services = new DefaultServices(this);

DefaultServices为ServicesContainer的一个子类,所以可以称之为服务容器,定义在System.Web.Http.Services命名空间下,在其构造函数中,有如下代码:

......
this.SetSingle<IHttpControllerActivator>(new DefaultHttpControllerActivator());
this.SetSingle<IHttpControllerSelector>(new DefaultHttpControllerSelector(configuration));
this.SetSingle<IHttpControllerTypeResolver>(new DefaultHttpControllerTypeResolver());
......

从红色部分这正是我所需要的找的controllerselector。

4、问题所在

从第2步中,如果通过源代码,可以发现:HttpControllerDispatcher 在处理request时,需要通过HttpControllerDescriptor对象的CreateController方法,才能最终实例化一个ApiController。而HttpControllerDescriptor是通过IHttpControllerSelector(默认就是DefaultHttpControllerSelector)的SelectController方法构造的。我进一步在DefaultHttpControllerSelector源码中,发现如下代码:

private ConcurrentDictionary<string, HttpControllerDescriptor> InitializeControllerInfoCache()
{
ConcurrentDictionary<string, HttpControllerDescriptor> dictionary = new ConcurrentDictionary<string, HttpControllerDescriptor>(StringComparer.OrdinalIgnoreCase);
HashSet<string> set = new HashSet<string>();
foreach (KeyValuePair<string, ILookup<string, Type>> pair in this._controllerTypeCache.Cache)
{
string key = pair.Key;
foreach (IGrouping<string, Type> grouping in pair.Value)
{
foreach (Type type in grouping)
{
if (dictionary.Keys.Contains(key))
{
set.Add(key);
break;
}
dictionary.TryAdd(key, new HttpControllerDescriptor(this._configuration, key, type));
}
}
}
foreach (string str2 in set)
{
HttpControllerDescriptor descriptor;
dictionary.TryRemove(str2, out descriptor);
}
return dictionary;
}

和HttpControllerTypeCache这样一个cache辅助类里的:

private Dictionary<string, ILookup<string, Type>> InitializeCache()
{
IAssembliesResolver assembliesResolver = this._configuration.Services.GetAssembliesResolver();
return this._configuration.Services.GetHttpControllerTypeResolver().GetControllerTypes(assembliesResolver).
GroupBy<Type, string>(t => t.Name.Substring(0, t.Name.Length - DefaultHttpControllerSelector.ControllerSuffix.Length), StringComparer.OrdinalIgnoreCase).
ToDictionary<IGrouping<string, Type>, string, ILookup<string, Type>>(g => g.Key,
g => g.ToLookup<Type, string>(t => (t.Namespace ?? string.Empty), StringComparer.OrdinalIgnoreCase), StringComparer.OrdinalIgnoreCase);
}

这就是问题所在,导致在同一个assembly中,不能有两个相同名字的api controller。否则就会执行:

ICollection<Type> controllerTypes = this._controllerTypeCache.GetControllerTypes(controllerName);
if (controllerTypes.Count == 0)
{
throw new HttpResponseException(request.CreateErrorResponse(HttpStatusCode.NotFound, System.Web.Http.Error.Format(SRResources.ResourceNotFound, new object[] { request.RequestUri }), System.Web.Http.Error.Format(SRResources.DefaultControllerFactory_ControllerNameNotFound, new object[] { controllerName })));
}
throw CreateAmbiguousControllerException(request.GetRouteData().Route, controllerName, controllerTypes);

controllerTypes.Count大于0,导致抛出“Multiple types were found that match the controller named…”异常。

解决问题

到现在为止,其实解决办法已经出来了:就是不用上面的两个方法,来构造HttpControllerDispatcher。

    
最新技术文章:
▪C#通过IComparable实现ListT.sort()排序
▪C#实现对Json字符串处理实例
▪Winform实现抓取web页面内容的方法
▪Winform实现将网页生成图片的方法
▪C#控制台程序中处理2个关闭事件的代码实例
▪WinForm实现同时让两个窗体有激活效果的特效...
▪WinForm实现拦截窗体上各个部位的点击特效实...
▪用C#的params关键字实现方法形参个数可变示例
▪C#判断某程序是否运行的方法
▪C#验证码识别基础方法实例分析
▪C#通过WIN32 API实现嵌入程序窗体
▪C#实现获取鼠标句柄的方法
▪C#事件处理和委托event delegate实例简述
▪C#获取程序文件相关信息的方法
▪C#中的除法运算符与VB.NET中的除法运算符
▪ASP.NET MVC 5使用X.PagedList.Mvc进行分页教程(PagedLi...
▪Base64编码解码原理及C#编程实例
▪C#实现的优酷真实视频地址解析功能(2014新算...
▪C#和SQL实现的字符串相似度计算代码分享
▪C#使用Word中的内置对话框实例
▪C#反射之基础应用实例总结
▪C#生成单页静态页简单实例
▪C#实现SMTP邮件发送程序实例
▪C#实现随鼠标移动窗体实例
▪C#使用GDI+创建缩略图实例
▪C#实现通过模板自动创建Word文档的方法
▪C#中Response.Write常见问题汇总
▪C#中多态、重载、重写区别分析
▪WinFrom中label背景透明的实现方法
▪C#中out保留字用法实例分析
 


站内导航:


特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

©2012-2021,,E-mail:www_#163.com(请将#改为@)

浙ICP备11055608号-3