如何实现Asp与Asp.Net共享Session

微软.net中,session的存储机制已经与asp的存储机制不一样,虽然可以在同一个iis下同时运行asp与aspx,但是它们之间不能传递session。
之前大批系统应用到了asp,在升级过程中,如果完全抛弃asp来重写,一来工作量太大,二来以前的成果不能保存下来。

所以微软提出了一个session共享的解决方案,只是此文档光说明原理,并没有说具体的操作步骤,由此,我撰文描述过程。

简单说明原理,asp与asp.net之间的session统一存储在数据库中来实现共享

1、创建数据表
打开sql server查询分析器,运行以下脚本来创建数据表,数据表名为sessionstate
if exists (select * from sysobjects where id = object_id(n'[dbo].[sessionstate]’) and objectproperty(id, n’isusertable’) = 1)
drop table [dbo].[sessionstate]
go

create table [dbo].[sessionstate] (
[id] uniqueidentifier not null ,
[data] [image] not null ,
[last_accessed] [datetime] not null
) on [primary] textimage_on [primary]
go

alter table [dbo].[sessionstate] with nocheck add
constraint [pk_sessionstate] primary key nonclustered
(
[id]
) on [primary]
go

2、下载以下文件 session.rar

将文件解压后,将产生4个文件,分别作如下操作。
复制 global.asa 到系统根目录下,并打开文件,修改application(“sessiondsn”) 为合适的数据库链接字符串,如果系统本身已经有了global.asa,则在此文件中添加如下application:
application(“sessiondsn”) = “initial catalog=sqlservername;persist security info=false;user id=sa;password=****;packet size=4096”
在系统的 web.config 文件中,添加此项
<add key=”sessiondsn” value=”data source=sqlservername;initial catalog=sessiondemodb;persist security info=false;user id=sessiondemodbuser;password=****;packet size=4096″ />
并将其值修改为合适的数据库链接。
将另外两个dll文件复制到系统目录下(或其他合适目录)

3、关闭iis中asp的session选项
打开iis,选择站点,依次选择属性 -> 主目录 -> 配置 -> 应用程序选项,将启用会话状况前的复选勾去除。如下图:
screen.width-350)this.width=screen.width-350″ border=0>

4、安装sessionutility.dll
首先找到 gacutil.exe 文件,一般情况下在 microsoft visual studio .net 2003\sdk\v1.1\bin 目录下
在命令提示符窗口中,执行 gacutil /i sessionutility.dll,(如果执行失败,请将这两个文件的路径都写全了)

5、注册sessionutility.dll为com对象
同样,要找到 regasm.exe 文件,一般情况下在 winnt\microsoft.net\framework\v1.1.4322 目录下
在命令提示符窗口中,执行 regasm.exe sessionutility.dll /tlb:sessionutility.tlb,(如果执行失败,请将这两个文件的路径都写全了)
这样就会产生出一个tlb文件,可当做普通的com组件来调用。

6、注册sessionmanager.dll
这个很简单了,在命令提示符窗口中,执行regsvr32 sessionmanager.dll

7、如果是ntfs格式的系统,请找到 sessionmgr.dll,右键点击,属性,将iusr_<machine_name>权限设置为可读和可执行。

至此,我们已经可以实现了asp与asp.net之间session共享了,那么怎么去用

在asp中,我们要如下使用:
页面开始端
dim session
set session = server.createobject(“sessionmgr.session2”)
session(“userid”) = …



页面结束端
set session = nothing ‘记得一定要释放哦

而在asp.net中,我们要如下使用:
首先,我们要添加对sessionutility的引用
然后,编码时,原来是这样的继承 public class webform1 : system.web.ui.page,修改为public class webform1 : msdn.sessionpage
这样在编码过程中就可以使用session(“userid”)这样的形式了。

注意:虽然session实现了共享,但是session的使用语法,相对于.net中新增的部分,就没有实现,毕竟要照顾asp
譬如session.remove,就不能用了。

 

IIS错误:cs0016:未能写入输出文件解决方法

cs0016:未能写入输出文件 解决方法

前些天发布一个网站,通过visual Studio 2005 发布的,部署好项目以后用户可以使用,但是不知为什么突然的就用不了了。访问发布网站时出现的错误页面如下:
//—————————————————–

编译错误
 说明: 在编译向该请求提供服务所需资源的过程中出现错误。请检查下列特定错误详细信息并适当的修改源代码
编译器错误信息: cs0016:未能写入输出文件
“c:”WINDOWS”Microsoft.NET”Framework”v2.0.50727″Temporary ASP.NET Files”root”….”*.dll–“拒绝访问”
源错误:
  [没有相关的源行]
//——————————————————
 
产生原因: 应用程序运行时产生的临时文件需要存放到c:”windows”temp 文件夹下 而运行基于microsoft  .net framework 框架下的应用程序 需要对temp 具有读写的权限 ,所以程序运行产生的临时文件不能存储或读取 ,或者路径不存在的情况下都会产生编译错误。
 
解决方法:
1  设置c:windows\temp 目录访问权限 temp–> 属性–>安全– > 添加network service –>并赋予其权限为 读 和 写–> 确定
(注意:操作系统为windows server2003 framework  版本在 1.1及以上)

2 设置发布网站的程序目录中bin文件夹的权限 同样添加 network service 并设置权限为读取、 运行  

3 执行以上两步操作设置后问题解决。
 

关于ASPNET在IIS一些问题的经验总结

很多开发人员对于IIS和ASPNET的安装等问题困扰,特此做下面的小

总结,请大家多交流!

iis 坏了修复办法!!!!!!!

 

一般IIS运行不了ASP.NET,试一下下面四种方法,99%有效:

1。.NET 安装的顺序应该是先装IIS,再装VS.NET,如果次序反了,

或者IIS重装了,就需要使用aspnet_regiis.exe -i来重新安装IIS

Mapping(主要用于aspx, asmx等文件的Extention的匹配)。在

C:\WINDOWS\Microsoft.NET\Framework\v1.0.3705目录下,运行下

面的命令:aspnet_regiis.exe -i

2。重设ASPNET的密码,然后在下面的目录中找到Machine.config文

件:%Systemroot%\Microsoft.NET\Framework\v1.0.3705\CONFIG

(Systemroot是你的安装目录),在<processModel>标识中添加/修

改:userName和password3。如果还不行,重装IIS,然后再按照方

法1进行操作4。如果你的机器是域控制器,你可以参考Q315158:

ASP.NET Does Not Work withASPNET Account on Domain

Controllerhttp://support.microsoft.com/default.aspx 

scid=KB;EN-US;Q315158&和你大致讲一下操作的步骤:

1。在Administrative Tools->Active Directory Users and

Computers中建立一个名为ASPUSER的用户,将该用户添加到用户组

中(默认情况下已在User Group中)

2。在Administrative Tools->Local Security Settings->Local

Policy->UserRight Assignment中,双击右栏的Log on as a batch

job项,在弹出的窗口中点击Add,选择或输入刚才建立的ASPUSER帐

号,确定。(需要重启机器)

3。确保ASPUSER帐号有相应文件、目录的访问权限4。在下面的目录

中找到Machine.config文件:%Systemroot%

\Microsoft.NET\Framework\v1.0.3705\CONFIG (Systemroot是你

的安装目录),在<processModel>标识中添加/修改:

userName=”DomainName\ASPUSER” password=”ASPUSERpassword” 其

中ASPUSERpassword是刚刚建立的ASPUSER的密码,DomainName是你的域名

最后把机器RESET一下!看看!应该OK了!

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/21aspnet/archive/2004/10/25/151217.aspx

Asp.Net构架(IHttpHandler)

引言
在Part.1中,我们了解了Http请求的处理过程以及其它一些运作原理。我们知道Http管道中有两个可用接口,一个是IHttpHandler,一个是IHttpModule,但在Part.1中,我并没有详细讲述如何对它们进行编程,只是轻描淡写地一笔带过。所谓学以致用,前面已经介绍了不少概念和原理。在本文中,我们通过几个范例来了解 IHttpHandler,看看掌握这些原理的实际用途。

IHttpHandler 概述
可能和我一样,很多Asp.Net开发人员都有过Asp的背景,以至于我们在开发程序的时候,通常都是在“页面级”上思考,也就是说我们现在正在做的这个页面应该有什么样的功能,是进行一个问卷调查还是一个数据库查询等等。而很少在“请求级”思考,考虑有没有办法来通过编码的方式来操控一个Http请求。

实际上,Framework提供了一系列的接口和类,允许你对于Http请求进行编程,而实现这一操作的一个主要的接口,就是 IHttpHandler(另一个是IHttpModule)。

应该还记得第一节中我们提到过 ISAPI,它根据文件名后缀把不同的请求转交给不同的处理程序。但是仔细看看就会发现:几乎一大半的文件都交给 aspnet_isapi.dll 去处理了。很明显,aspnet_isapi.dll 不可能对每种文件采用同一种方式处理,那么 aspnet_isapi.dll 是如何更进一步处理不同的文件,交由谁去处理呢?为了搞清楚这个问题,我们需要打开机器上C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\CONFIG\ 目录下的web.config 文件。

NOTE:我查阅了很多资料,都说是在 machine.config 中,但实际上 v2.0.50727 下的machine.config中httpHandlers结点是这样的:<httpHandlers />,并没有给出详细的处理程序,在Web.config中才能看到。而v1.1.4322 下的machine.config中却有。

找到httpHandlers结点,应该可以看到如下这样的代码(做了省略):

<httpHandlers>

… …
<add path=”*.axd” verb=”*” type=”System.Web.HttpNotFoundHandler” validate=”True” />

<add path=”*.aspx” verb=”*” type=”System.Web.UI.PageHandlerFactory” validate=”True” />
<add path=”*.ashx” verb=”*” type=”System.Web.UI.SimpleHandlerFactory” validate=”True” />
<add path=”*.asax” verb=”*” type=”System.Web.HttpForbiddenHandler” validate=”True” />
<add path=”*.ascx” verb=”*” type=”System.Web.HttpForbiddenHandler” validate=”True” />
<add path=”*.config” verb=”*” type=”System.Web.HttpForbiddenHandler” validate=”True” />
<add path=”*.cs” verb=”*” type=”System.Web.HttpForbiddenHandler” validate=”True” />
<add path=”*” verb=”GET,HEAD,POST” type=”System.Web.DefaultHttpHandler” validate=”True” />
… …
</httpHandlers>

可以看到,在<httpHandlers>结点中将不同的文件类型映射给不同的Handler去处理,对于.aspx来说,是由System.Web.UI.PageHandlerFactory来处理。而对于.cs来说,是由System.Web.HttpForbiddenHandler 处理,从ForbiddenHandler名字中出现的Forbidden (翻译过来是“禁止”)可以看出,这个Handler可以避免我们的源码被看到。

NOTE:System.Web.UI.PageHandlerFactory 是一个IHttpHandlerFactory,而不是一个单一的HttpHandler,IHttpHandlerFactory用来做什么后面会说明。

上面列出的是.Net Framework在处理Http请求时的所采用的默认Handler。而如果我们要用编程的方式来操控一个Http请求,我们就需要实现IHttpHandler接口,来定制我们自己的需求。

IHttpHandler的定义是这样的:

public interface IHttpHandler{

void ProcessRequest(HttpContext context);

bool IsReusable { get; }

}

由上面可以看出IHttpHandler要求实现一个方法和一个属性。其中 ProcessRequest,从名字(处理请求)看就知道这里应该放置我们处理请求的主要代码。

IsReusable属性,MSDN上是这样解释的:获取一个值,该值指示其他请求是否可以使用 IHttpHandler 实例。也就是说后继的Http请求是不是可以继续使用实现了该接口的类的实例,一般来说,我把它设置成true。

那么实现此接口的类形式应该是这样的:

public class CustomHandler : IHttpHandler{

public void ProcessRequest(HttpContext context) {

// 处理请求的代码

}

public bool IsReusable {

get { return true; }

}

}

而为了能使用这个自定义的HttpHandler,我们需要在应用程序目录下的Web.config中注册它。

<system.web>

<httpHandlers>

<add path=”*.jpg” verb=”*” type=”MyNameSpace.MyClass, MyDllName” />

</httpHandlers>

</system.web>

应该发现这与之前在C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\CONFIG\目录下web.config中看到的几乎完全一样。这里,path指的是请求的文件名称,可以使用通配符扩大范围,也可以明确指定这个handler仅用于处理某个特定的文件(比如说:filename.aspx)的请求。verb指的是请求此文件的方式,可以是post或get,用*代表所有访问方式。type属性由“,”分隔成两部分,第一部分是实现了接口的类名,第二部分是位于Bin目录下的编译过的程序集名称。

NOTE:如果你新建一个项目,并且在项目下创建HandlerTest.cs,然后让站点引用该项目,那么在生成解决方案的时候会自动将编译好的.dll文件添到Bin目录中。

NOTE:MyDll只写程序集名,不要加后面的.dll。

使用HttpHandler实现图片防盗链
有了之前这么多的准备知识,实现现在的目标就容易得多了:

NOTE:这个例子,以及下面的一个例子均来自于《Maximizing ASP.NET Real World, Object-Oriented Development》一书:

Step.1:创建文件 CustomHandler.cs,代码如下:
using System;

using System.Web;

namespace CustomHandler{

public class JpgHandler : IHttpHandler{

public void ProcessRequest(HttpContext context){

// 获取文件服务器端物理路径

string FileName = context.Server.MapPath(context.Request.FilePath);

// 如果UrlReferrer为空,则显示一张默认的禁止盗链的图片

if (context.Request.UrlReferrer.Host == null){

context.Response.ContentType = “image/JPEG”;

context.Response.WriteFile(“/error.jpg”);

}else{

// 如果 UrlReferrer中不包含自己站点主机域名,则显示一张默认的禁止盗链的图片

if (context.Request.UrlReferrer.Host.IndexOf(“yourdomain.com”) > 0){

context.Response.ContentType = “image/JPEG”;

context.Response.WriteFile(FileName);

}else{

context.Response.ContentType = “image/JPEG”;

context.Response.WriteFile(“/error.jpg”);

}

}

}

public bool IsReusable{

get{ return true; }

}

}

}

Step.2 编译这个文件
csc /t:library /r:System.Web.dll CustomHandler.cs

Step.3 将编译好的 CustomHandler.dll 拷贝到站点的 Bin 目录下。
Step.4 在Web.Config 中注册这个Handler。
<system.web>

<httpHandlers>

<add path=”*.jpg” verb=”*” type=”CustomHandler.JpgHandler, CustomHandler” />

</httpHandlers>

</system.web>

OK,诸位可以按步骤自行测试一下,这里就不赘述了。

通过IhttpHandler实现图片验证码
也可以在一个.ashx文件中实现IHttpHandler,而不是采用这种提前编译的方式。

Step.1 打开Vs2005,“添加新项”,“一般处理程序”。新建文件后,VS会自动在文件中添加如下的代码:
<%@ WebHandler Language=”C#” Class=”Handler” %>

using System;

using System.Web;

public class Handler : IHttpHandler {

public void ProcessRequest (HttpContext context) {

context.Response.ContentType = “text/plain”;

context.Response.Write(“Hello World”);

}

public bool IsReusable {

get {

return false;

}

}

}

Step.2 将代码改写成如下所示:
<%@ WebHandler Language=”C#” Class=”Handler” %>

using System;

using System.Drawing;

using System.Drawing.Imaging;

using System.Text;

using System.Web;

using System.Web.SessionState;

public class Handler : IHttpHandler, IRequiresSessionState {

public void ProcessRequest(HttpContext context) {

context.Response.ContentType = “image/gif”;

//建立Bitmap对象,绘图

Bitmap basemap = new Bitmap(200, 60);

Graphics graph = Graphics.FromImage(basemap);

graph.FillRectangle(new SolidBrush(Color.White), 0, 0, 200, 60);

Font font = new Font(FontFamily.GenericSerif, 48, FontStyle.Bold, GraphicsUnit.Pixel);

Random r = new Random();

string letters = “ABCDEFGHIJKLMNPQRSTUVWXYZ”;

string letter;

StringBuilder s = new StringBuilder();

//添加随机的五个字母

for (int x = 0; x < 5; x++) {

letter = letters.Substring(r.Next(0, letters.Length – 1), 1);

s.Append(letter);

graph.DrawString(letter, font, new SolidBrush(Color.Black), x * 38, r.Next(0, 15));

}

//混淆背景

Pen linePen = new Pen(new SolidBrush(Color.Black), 2);

for (int x = 0; x < 6; x++)

graph.DrawLine(linePen, new Point(r.Next(0, 199), r.Next(0, 59)), new Point(r.Next(0, 199), r.Next(0, 59)));

//将图片保存到输出流中

basemap.Save(context.Response.OutputStream, ImageFormat.Gif);

context.Session[“CheckCode”] = s.ToString(); //如果没有实现IRequiresSessionState,则这里会出错,也无法生成图片

context.Response.End();

}

public bool IsReusable {

get { return true; }

}

}

需要特别注意的是,Handler类不仅需要实现 IHttpHandler接口(这个显然),为了在这个Handler类中使用SessionState,还需要实现IRequiresSessionState接口,对于这个接口,MSDN的解释是这样的:Specifies that the target HTTP handler requires read and write access to session-state values. This is a marker interface and has no methods.(翻译过来是:指定当前Http Handler需要对SessionState值的读写访问权。这是一个标记接口,没有任何方法)。

而实际上,IRequiresSessionState的接口定义是这样的:

public interface IRequiresSessionState

{

}

可见,这个接口没有任何需要实现的方法或属性,大家只要记得:如果想在HttpHandler中使用SessionState,必须实现这个接口,实际上也就是在类的标头将这个接口加进去。

Step.3 新建一个ImageCode.aspx页面,在HTML代码中写下:
<img src=”Handler.ashx” alt=”图片验证码” />

OK,在浏览器中打开ImageCode.aspx,应该可以看到如下所示:

利用HttpHandler创建自定义后缀Rss源
RSS如今已经可以说是随处可见,而RSS的实现方式,通常是在一个.aspx的CodeBehind文件中写一个XML文件,然后加载到Response的OutputStream中, Rss源通常是Rss.aspx这种形式的。通过第一章学到的ISAPI的知识,再结合本章学到的关于HttpHandler的知识,很容易想到:我们可以自定一个以 .rss 作为后缀名的文件来实现 Rss 源,比如说Article.rss。现在我们就一步步来实现它:

NOTE:关于RSS的更多内容,可以参阅我编译的《在Web站点中创建和使用RSS源》。本文不再解释Rss是什么,如何创建Rss源,为了文章的独立性,仅给出创建过程。

Step.1 创建范例数据库
Create Table RssSample

(

SampleId Int Identity(1,1) Not Null,

Title Varchar(100) Not Null Constraint uq_Title Unique,

Author Varchar(50) Not Null,

PubDate DateTime Not Null Default GetDate(),

[Description] Varchar(500) Not Null,

Link Varchar(150) Not Null

Constraint pk_RssSample Primary Key(SampleId)

)

— 插入范例数据

Insert Into RssSample(Title, Author, [Description], Link)

Values(‘标题1’, ‘作者1’, ‘文章摘要1’, ‘http://127.0.0.1/#’ )

— 省略 ….

Step.2 建立站点,在App_Code目录下建立RssFeedsLib.cs文件。
using System;

using System.Data;

using System.Data.SqlClient;

using System.IO;

using System.Web;

using System.Xml;

using System.Text;

namespace RssFeadsLib {

public class RssGenerator {

public static string GetRSS() {

MemoryStream ms = new MemoryStream();

XmlTextWriter writer = new XmlTextWriter(ms, null);

SqlConnection conn = new SqlConnection(“Data Source=.;Initial Catalog=Sample;User ID=sa;Password=sa”); //修改这里成你的数据库连接

SqlCommand cmd = new SqlCommand(“select * from RssSample order by pubdate desc”, conn);

conn.Open();

SqlDataReader reader = cmd.ExecuteReader();

writer.WriteStartElement(“rss”);

writer.WriteAttributeString(“version”, “2.0”);

writer.WriteStartElement(“channel”);

// Channel 下的结点静态写入

writer.WriteElementString(“title”, “TraceFact.Net 技术文章”);

writer.WriteElementString(“link”, “http://www.jzxue.com”);

writer.WriteElementString(“description”, “Dedicated to asp.net…”);

writer.WriteElementString(“copyright”, “Copyright (C) 2007”);

writer.WriteElementString(“generator”, “My RSS Generator”);

// Item 结点从数据库读取

while (reader.Read()) {

writer.WriteStartElement(“item”);

writer.WriteElementString(“author”, reader.GetString(reader.GetOrdinal(“Author”)));

writer.WriteElementString(“title”, reader.GetString(reader.GetOrdinal(“title”)));

writer.WriteElementString(“link”, reader.GetString(reader.GetOrdinal(“Link”)));

writer.WriteElementString(“description”, reader.GetString(reader.GetOrdinal(“Description”)));

writer.WriteElementString(“pubDate”, reader.GetDateTime(reader.GetOrdinal(“PubDate”)).ToString(@”ddd, dd MMM yyyy 12:00:00 tt “));

writer.WriteEndElement();

}

writer.WriteEndElement();

writer.WriteEndElement();

reader.Close();

conn.Close();

writer.BaseStream.Flush();

writer.Flush();

ms.Flush();

// 将流转换成String并返回

byte[] data = new byte[ms.Length];

ms.Seek(0, SeekOrigin.Begin);

ms.Read(data, 0, data.Length);

ms.Close();

return UTF8Encoding.UTF8.GetString(data);

}

}

}

Step.3 创建可以处理 .rss 后缀名的 RssHandler
我们在这个 RssFeedsLib命名空间下,再添加一个类,这个类用于处理对 .rss 后缀名文件的Http请求。

public class RSSHandler:IHttpHandler{

public bool IsReusable

{

get {return false;}

}

public void ProcessRequest(HttpContext context){

context.Response.ContentType = “text/xml”;

string str = RssGenerator.GetRSS();

context.Response.Write(str);

}

}

Step.4 在Web.config中进行配置
<httpHandlers>

<add path=”*.rss” type=”RssFeadsLib.RSSHandler” verb=”GET” />

</httpHandlers>

NOTE:因为这个类和命名空间位于App_Code中,这里就不需要再手动编译RssFeadsLib.cs然后将编译好的.dll应用程序集放到Bin目录中了。至于为什么可以这样,将会在 《Asp.Net 构架与安全机制 Part.5 – 页面生存周期与编译模型》中解释。

Step.5 在IIS 对ISAPI进行设置。
应该还记得在Part.1中如何在IIS中设置ISAPI来进行文件与处理程序映射:

1. 打开IIS,选择本范例所用的站点,右键,选择“属性”。

2. 选择“主目录”选项卡,点击“配置…”按钮。

3. 点击“添加”,设置“可执行文件”为“C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll”,设置“扩展名”为“.rss”,点“确定”。

4. 注意,不要勾选“检查文件是否存在”复选框,这样不用创建文件,只要在地址栏输入任意以.rss后缀结尾的文件名,均会交由上面创建的Handler去处理,而不管这个文件是否存在,也不管请求的是Article.rss还是Sample.rss。

进行了这些设置以后,现在IIS就知道如何去处理对.rss后缀名文件的请求了。

Step.6 测试范例
这个时候,随便打开一个页面,比如空白的Default.aspx,然后我们在地址栏将文件改为:Article.rss(改成abc.rss也是一样),敲回车,应该可以看到如下的画面。

IHttpHandlerFactory 概述
现在假设我们有这样的需求,我们不仅想要处理 .rss 后缀名,还想要能够处理 .atom后缀名,假设处理atom的类命名为AtomHandler,那么我们的Web.config该如何设置呢?我想应该是这样的:

<httpHandlers>

<add path=”*.rss” type=”RssFeadsLib.RSSHandler” verb=”GET” />

<add path=”*.atom” type=”RssFeadsLib.AtomHandler” verb=”GET” />

</httpHandlers>

如果我们有很多个HttpHandler分别映射不同后缀名的请求,这样我们的Web.config会变得很冗长,或者,我们只有在程序运行时才能确切地知道使用哪个Handler,这个时候,可以考虑实现 IHttpHandlerFactory来完成这一过程。

IHttpHandlerFactory的定义是这样的:

public interface IHttpHandlerFactory{

IHttpHandler GetHandler(HttpContext context, string requestType, string url, string pathTranslated);

void ReleaseHandler(IHttpHandler handler);

}

可见,需要实现两个方法,分别是 GetHandler() 和 ReleaseHandler()。

l GetHandler(),返回实现了IHttpHandler接口的类的实例。

l ReleaseHandler(),使得Factory可以重复使用一个已经存在的Handler实例。

对于上面 .atom 和 .rss 的问题,我们可以这样来实现 IHttpHandlerFactory接口:

class HandlerFactory:IHttpHandlerFactory{

public IHttpHandler GetHandler(HttpContext context, string requestType, string url, string pathTranslated){

string path = context.Request.PhysicalPath;

if (Path.GetExtension(path) == “.rss”){

return new RSSHandler();

}

if (Path.GetExtension(path) == “.atom”){

return new ATOMHandler();

}

return null;

}

public void ReleaseHandler(IHttpHandler handler){

}

}

这时,在Web.Config 中<system.web>节点下进行如下设置即可:

<httpHandlers>

<add path=”*.rss,*.atom” type=” RssFeadsLib.HandlerFactory” verb=”GET” />

</httpHandlers>

但是,这不能简化IIS中ISAPI的设置,还是需要手动去对.rss和.atom分别设置。

总结
在本文中,我们首先讨论了aspnet_isapi.dll 如何将对不同后缀名文件的请求分发给相应的处理程序,如何查看Framework默认的处理程序Handler。

然后,我们通过三个实例,图片防盗链、图片验证码、处理自定义后缀名请求,详细讲解了IHttpHandler的实现方法和使用过程。

最后,我向大家概要地介绍了IHttpHandlerFactory接口。

希望这篇文章能给你带来帮助。

系列导航

iis权限设置,保证服务器安全

 

  如何设置 Web 服务器的权限?如果Web服务器的权限没有设置好,那么网站就会出现漏洞并且很可能会出现被不怀好意的人黑掉的情况。我们不应该把这归咎于 IIS 的不安全。如果对站点的每个目录都配以正确的权限,出现漏洞被人黑掉的机会还是很小的(Web 应用程序本身有问题和通过其它方式入侵黑掉服务器的除外)。下面是我在配置过程中总结的一些经验,希望对大家有所帮助。

  IIS Web 服务器的权限设置有两个地方,一个是 NTFS 文件系统本身的权限设置,另一个是 IIS 下网站->站点->属性->主目录(或站点下目录->属性->目录)面板上。这两个地方是密切相关的。下面以实例的方式来讲解如何设置权限。

IIS 下网站->站点->属性->主目录(或站点下目录->属性->目录)面板上有:

脚本资源访问
读取
写入
浏览
记录访问
索引资源
  6 个选项。这 6 个选项中,“记录访问”和“索引资源”跟安全性关系不大,一般都设置。但是如果前面四个权限都没有设置的话,这两个权限也没有必要设置。在设置权限时,记住这个规则即可,后面的例子中不再特别说明这两个权限的设置。

  另外在这 6 个选项下面的执行权限下拉列表中还有:


纯脚本
纯脚本和可执行程序
3 个选项。

  而网站目录如果在 NTFS 分区(推荐用这种)的话,还需要对 NTFS 分区上的这个目录设置相应权限,许多地方都介绍设置 everyone 的权限,实际上这是不好的,其实只要设置好 Internet 来宾帐号(IUSR_xxxxxxx)或 IIS_WPG 组的帐号权限就可以了。如果是设置 ASP、PHP 程序的目录权限,那么设置 Internet 来宾帐号的权限,而对于 ASP.NET 程序,则需要设置 IIS_WPG 组的帐号权限。在后面提到 NTFS 权限设置时会明确指出,没有明确指出的都是指设置 IIS 属性面板上的权限。

例1 —— ASP、PHP、ASP.NET 程序所在目录的权限设置:
  如果这些程序是要执行的,那么需要设置“读取”权限,并且设置执行权限为“纯脚本”。不要设置“写入”和“脚本资源访问”,更不要设置执行权限为“纯脚本和可执行程序”。NTFS 权限中不要给 IIS_WPG 用户组和 Internet 来宾帐号设置写和修改权限。如果有一些特殊的配置文件(而且配置文件本身也是 ASP、PHP 程序),则需要给这些特定的文件配置 NTFS 权限中的 Internet 来宾帐号(ASP.NET 程序是 IIS_WPG 组)的写权限,而不要配置 IIS 属性面板中的“写入”权限。

  IIS 面板中的“写入”权限实际上是对 HTTP PUT 指令的处理,对于普通网站,一般情况下这个权限是不打开的。

  IIS 面板中的“脚本资源访问”不是指可以执行脚本的权限,而是指可以访问源代码的权限,如果同时又打开“写入”权限的话,那么就非常危险了。

  执行权限中“纯脚本和可执行程序”权限可以执行任意程序,包括 exe 可执行程序,如果目录同时有“写入”权限的话,那么就很容易被人上传并执行木马程序了。

  对于 ASP.NET 程序的目录,许多人喜欢在文件系统中设置成 Web 共享,实际上这是没有必要的。只需要在 IIS 中保证该目录为一个应用程序即可。如果所在目录在 IIS 中不是一个应用程序目录,只需要在其属性->目录面板中应用程序设置部分点创建就可以了。Web 共享会给其更多权限,可能会造成不安全因素。

总结: 也就是说一般不要打开-主目录-(写入),(脚本资源访问) 这两项以及不要选上(纯脚本和可执行程序),选(纯脚本)就可以了.需要asp.net的应用程序的如果应用程序目录不止应用程序一个程序的可以在应用程序文件夹上(属性)-目录-点创建就可以了.不要在文件夹上选web共享.

例2 —— 上传目录的权限设置:
  用户的网站上可能会设置一个或几个目录允许上传文件,上传的方式一般是通过 ASP、PHP、ASP.NET 等程序来完成。这时需要注意,一定要将上传目录的执行权限设为“无”,这样即使上传了 ASP、PHP 等脚本程序或者 exe 程序,也不会在用户浏览器里就触发执行。

  同样,如果不需要用户用 PUT 指令上传,那么不要打开该上传目录的“写入”权限。而应该设置 NTFS 权限中的 Internet 来宾帐号(ASP.NET 程序的上传目录是 IIS_WPG 组)的写权限。

  如果下载时,是通过程序读取文件内容然后再转发给用户的话,那么连“读取”权限也不要设置。这样可以保证用户上传的文件只能被程序中已授权的用户所下载。而不是知道文件存放目录的用户所下载。“浏览”权限也不要打开,除非你就是希望用户可以浏览你的上传目录,并可以选择自己想要下载的东西。

总结: 一般的一些asp.php等程序都有一个上传目录.比如论坛.他们继承了上面的属性可以运行脚本的.我们应该将这些目录从新设置一下属性.将(纯脚本)改成(无).

例3 —— Access 数据库所在目录的权限设置:
  许多 IIS 用户常常采用将 Access 数据库改名(改为 asp 或者 aspx 后缀等)或者放在发布目录之外的方法来避免浏览者下载它们的 Access 数据库。而实际上,这是不必要的。其实只需要将 Access 所在目录(或者该文件)的“读取”、“写入”权限都去掉就可以防止被人下载或篡改了。你不必担心这样你的程序会无法读取和写入你的 Access 数据库。你的程序需要的是 NTFS 上 Internet 来宾帐号或 IIS_WPG 组帐号的权限,你只要将这些用户的权限设置为可读可写就完全可以保证你的程序能够正确运行了。

总结: Internet 来宾帐号或 IIS_WPG 组帐号的权限可读可写.那么Access所在目录(或者该文件)的“读取”、“写入”权限都去掉就可以防止被人下载或篡改了

例4 —— 其它目录的权限设置:
  你的网站下可能还有纯图片目录、纯 html 模版目录、纯客户端 js 文件目录或者样式表目录等,这些目录只需要设置“读取”权限即可,执行权限设成“无”即可。其它权限一概不需要设置。

  上面的几个例子已经包含了大部分情况下的权限设置,只要掌握了设置的基本原理,也就很容易地完成能其它情况下的权限设置。

 

Win2003中apache2分别整合tomcat5和iis6的终极教程

 2006年5月18日:一个值得记住的日子

    为了能在已经存在iis6的服务器上运行自己的java程序,经过历时半年的尝试,今天终于搞定了,好开心啊。
   
    最开始是用iis直接连接tomcat,找遍了网上所有的资料,可是死活也连不通,或许是iis的封闭吧,看来tomcat与iis远没有成为朋友。
于是只好另辟蹊径,用apache监听80来做请求转发了,请求到iis的站点就转到相应目录,请求到tomcat下的站点就转发到tomcat下,于是开始到处找这方面的资料,终于经过反复试验,右克服请求servlet出错的困难,现在终于可以继续做自己的网站了。

参考文档:
1.http://weblife.blogbus.com/s1659/index.html
2.http://wiki.osportfolio.org/confluence/display/Technical/Apache+Tomcat+mod_jk+Integration

第一篇文档基本解决了所有的问题,第二篇文档解决了请求servlet发生找不到目标的问题

下面就从零开始,一步步配置三个服务器,让他们协调工作。

    1.下载安装apache2
   
    在http://bj.onlinedown.net/soft/11528.html中下载apache2.0.55 for windows
    在官方网站上我怎么也找不到,奇怪。下载到本地后双击就可以安装了,安装完成后应该在系统托盘中看到一个小图标了,是个羽毛加绿色播放箭头的图标,这表示正确安装了,如果不能正确安装,请确认80端口没有被别的服务器占有。
   
    2.下载安装tomcat5
   
    Tomcat还是到官方网站下载,地址是:http://tomcat.apache.org/download-55.cgi,选择5.5.17中core:zip,我比较习惯用这个压缩包,解压后设置环境变量就可以用了。在安装路径的bin里面运行startup.bat就可以启动tomcat了。
   
    3.安装IIS6.0
   
    将win2003的安装盘插入光驱,在添加或删除程序中选择“添加/删除windows组件”在“windows组件向导”中选择“应用程序服务器”并打上勾,按向导提示下一步进行,就可以安装了。IIS6.0安装后并不能正常启动,因为默认端口80被apache已经占了。双击打开“管理工具/internet信息服务(IIS)管理器”,在“默认网站(停止)”上右击选择“属性”,在“网站”选项卡中修改“TCP端口”的80为88或者其他端口,确定。选中“默认网站(停止)”然后单击工具栏中的播放图标,就可以启动IIS了,正常启动后“停止”字样就消失了。
   
    4.测试3个服务器
   
    修改Apache安装目录/htdocs中的index.html.en改名为index.html,在浏览器输入http://localhost回车如果看到apache的欢迎界面,说明apache正在运行。在浏览器中输入http://localhost:8080回车如果看到tomcat的欢迎界面,这表示tomcat运行正常。在浏览器中输入http://localhost:88回车如果看到“建设中”这样的提示,表示iis正在运行。
   
    5.配置apache与tomcat的连接
   
    第一步: 在http://www.apache.org/dist/tomcat/tomcat-connectors/jk/binaries/win32/jk-1.2.6
             下载mod_jk_1.2.6_2.0.50.dll文件,将其改名为mod_jk.so后放到apache2/modules目录中。
            
    第二步: 打开记事本,输入下列语句,以workers.properties为文件名保存在tomcat安装目录/conf目录下:
   
             workers.tomcat_home=C:\Program Files\jakarta-tomcat-5.0.28
             workers.java_home=C:\Program Files\Java\jdk1.5.0_06
             ps=\
             worker.list=ajp13
             worker.ajp13.port=8009
             worker.ajp13.host=localhost
             worker.ajp13.type=ajp13
             worker.ajp13.lbfactor=1
            
     第三步:用记事本打开apache/conf/httpd.conf文件末尾,添加下面一段:
    
     LoadModule jk_module modules/mod_jk.so
     JkWorkersFile “D:\Program Files\jakarta-tomcat-5.0.28\conf\workers.properties”

     <VirtualHost *:80>
       ServerAdmin rabbit69@openria.com   
       ServerName localhost
       DirectoryIndex index.html index.htm index.jsp
       JkMount /* ajp13   
       JkAutoAlias “C:\Program Files\jakarta-tomcat-5.0.28\webapps”  
       <Directory “C:\Program Files\jakarta-tomcat-5.0.28\webapps”>
          Options Indexes FollowSymLinks
          allow from all
       </Directory>
     </VirtualHost>       

     保存,停止apache服务,在启动,就可以将新配置应用了。
    
     6.测试apache与tomcat的连接
     在服务器中输入http://localhost回车如果看见的是tomcat的欢迎界面,就表示apache和tomcat整合成功了,localhost后面加上jsp-examples目录或者servlet-examples目录就可以看到下面的例子,为了让servlet运行,我可是费了半天劲,修改这个httpd.conf文件。
    
     7.配置apache与IIS6的连接
    
     第一步:修改httpd.conf文件,启用proxy模块
             将文件中的LoadModule proxy_module modules/mod_proxy.so和LoadModule proxy_http_module modules/mod_proxy_http.so这两句
             的“#”去掉就可以了。
            
     第二步:增加IIS的虚拟主机
             在httpd.conf文件末尾加入以下代码:
            
             <VirtualHost *:80>
                ServerAdmin rabbit69@openria.cn
                ServerName localhost
                DocumentRoot “C:/Inetpub/wwwroot”
                DirectoryIndex index.html index.htm index.asp
                Alias /test “C:/Inetpub/wwwroot”
                <Directory “C:/Inetpub/wwwroot”>
                   Options MultiViews
                   AllowOverride None
                   Order allow,deny
                   Allow from all
                </Directory>
                ProxyPass / http://127.0.0.1:88/
                ProxyPassReverse / http://127.0.0.1:88
             </VirtualHost>
             保存,并重启apache就可以做测试了。
            
      8.测试apaceh与IIS的连接
     
      写一个asp页面,hello.asp:
      <HTML>
         <HEAD>
           <TITLE>Hello World Sample</TITLE>
         </HEAD>
         <BODY>
           <% Response.Write “Hello World” %>
         </BODY>
      </HTML>
      放到C:/Inetpub/wwwroot下面,在浏览器中访问http://localhost/test/hello.asp回车如果出现“hello world”字样就表示配置成功了。如果页面出现空白,在Internet信息服务(IIS)管理器中的web服务扩展里将“active server page”允许,然后清空缓存,刷新页面应该就可以看见hello world了。
     
      具体参数的含义就不多说了,上面的参考文档有介绍。
     
      后记:
     
      一直以为这个整合问题解决不了了,但是我还是不甘心,为什么别人能调通,我就调不通,苦脑啊,今天终于解决了,昨天晚上还弄到1点多,所有的辛苦没有白下,写下这个,做个纪念,也希望能对碰到此问题的网友有帮助,没有互联网就没有大家的成长。

用.NetRemoting访问远程对象

.Net Remoting访问远程对象

Net提供了好几种通信协议与方式使得这种开发变得简单而快速,你甚至无需知道太多的传输协议与编码细节。因此,无论你开发一个web应用还是关键的、涉及多操作系统和多通信协议的企业级应用,.Net都将对你提供全面的支持。跨进程的对象通信技术一直是个复杂的工作,现在这些复杂的处理工作都交给.Net framework来完成了。

.Net Remoting能使客户端应用调用位于本机或者网络上其他进程中的对象,你也可以利用.Net Remoting调用同一个进程中不同应用域中的对象。.Net Remoting提供了一种可以把远程对象的通信机制从特定服务器和客户端中分离出来的抽象方法,因此,它是灵活的、方便的,并且是易于定制的。你可以更换通信协议和交换格式,而无需重新编译客户端和服务器端应用。另外,这个远程机制并不针对任何特定的应用模式,你可以从一个web application、一个主控台应用、一个windows service———甚至是任何你需要的系统发起调用。远程服务器也可以是任何类型的可执行系统,任何应用都可以宿主/容纳(作为一个对象容器)一个远程对象并且对任何客户端提供该远程对象的服务。

选择.Net调用协议

.Net Framework提供了好几种面对不同应用域的对象调用方法,每一种方式都有其独特的技术与弹性。比如,Internet的快速成长使得XML/Web Service成为一种极富诱惑力的通信手段,因为Web Service建立在Http协议和以XML作为交换格式的Soap协议之上,而这一基础架构普遍存在。它们已经是公共标准,可以在web架构中随时使用,而不用担心访问代理和防火墙的问题。

但是,并非所有的应用都应该使用Web Service,基于Http连接的Soap数据流传输(serialization)存在严重的效率问题。这里我们将探讨那一种对象互操作协议适合于你的应用。

Asp.net 还是 Remoting 

Asp.net.net remoting都是进程间通信的实现方式。Asp.net基于IIS,这种基础架构已为开发者熟悉。.net remoting则是一种更加一般性的、扩展的进程间互操作机制。通过.net remoting你不仅可以产生基于IISXML Web Service服务(和包括安全性、延展性、sessionASP.netIIS等应用形态),也可以产生任何其他通信协议和传输格式的应用。

你需要的通信方式和你熟悉的开发模式是你选择Asp.net或者remoting的两条基本准则。无论你如何选择,你需要用最简单的方法达到你的目标。

下面是一些根据优先级排列的互操作通信协议(XML web service built with asp.net, XML web service built with .net remoting)的选择原则。

1)安全性

如果你注重调用的安全性,无论是一个ASP.net应用还是一个remoting应用,你必须使用宿主在IIS上的基于HTTP的应用模式。这是因为Asp.net.net remoting使用IIS提供的安全性服务。.net remoting并不提供位于IIS之外的独立的安全性策略,比如在一个windows service应用之中。

尽管你可以在任何应用域中使用.net remoting(不像用asp.net构建的xml web service,必须寄生/宿主在IIS中),但是你必须独立提供安全性服务,除非你的.net remoting应用基于IIS

如果你使用HTTP连接,你无需使用XML/SOAP封包格式,你可以使用二进制编码来提升传输速度。

2)速度

在用ASP.net构建的XML Web Services中,.Net Remoting具备潜在的性能优势,因为.net remoting允许你使用二进制编码与缺省的tcpchannel,这将导致极好的互操作性能。即使你不使用缺省的tcpchannel,你依然可以在httpchannel(基于IIS或者任何httpchannel侦听程序)中指定二进制编码传输格式。

使用二进制编码传输可以显著的提高调用效率,即使你使用httpchannel而不是用tcpchannel. 如果你并不关心安全性问题,比如你的系统运行在防火墙区域内,那么采用httpchannel和二进制编码传输是最佳选择。

当不需要使用.net remoting时,用Asp.net构建的Xml web services常常使用soap封包,其效率低于二进制编码传输,但也能提供较好的执行性能。

3)互操作

如果你希望在不同的操作系统之间互操作,那么无论是asp.net还是.net remoting,你典型地需要使用soap协议。基于asp.netxml web services.net remoting提供更多的soap封包定制的灵活性,这将是不同平台之间的互操作变得更加容易。

当然,你也可以使用.net remoting实施不同操作系统的互操作,.net remoting优先用于同.net客户端的通信。

4)伸缩性

如果你的应用宿主在IIS中,将给你最大的伸缩性,无论使用.net remoting还是asp.net.

5)使用CLR特性

因为.net remoting优先用于.net client的通信,那么有下述基于asp.netxml web services所不具备的clr特性可用。

    • interfaces.
    • CallContext.
    • properties.
    • indexers.
    • Managed Extensions for C++.
    • Type fidelity between the client and server applications.
    • delegates.

    6)面向对象的应用设计

    asp.net构建的xml web services应用并非面向对象的设计范例,它们本质上都是一些无状态的web资源,比如web page等等,尽管IISASP.net基础架构提供了一些状态服务。

    .net remoting对象则是真正意义上的对象,它们具有面向对象的所有特征,而这些特征则是asp.net所不具备的。

    l 远程对象的引用

    l 多种对象激活机制

    l 面向对象的状态管理

    l 分布式对象生命周期管理

    下面介绍一下用asp.net构建的xml web servicessystem.net 命名空间和.net remoting之间的区别。

    XML Web Services

    如果你希望用web application模型构建具有强大asp.net http运行时支持的asp应用,包括强大的Microsoft Visual Studio.Net的支持,那么用asp.net 构建xml web services是的选择。

    由于xml web services的基础架构,你能够很容易的产生攻其他应用使用的组件,或者使用其他应用的组件。但是两台计算机之间的精确数据类型并不被支持,仅能传递一些参数。

    System.Net Namespace

    你能使用syste.net namespace中的类从底至上构建一个完整的对象调用结构,你也能使用system.net类架构一些嵌入到remoting体系结构中的通信协议和数据传输格式。

    .Net Remoting

    .net remoting提供了沟通对象间调用的工具,包括但不限于xml web services.使用.net remoting,你可以做到:

    l 在任何应用域中发布和使用对象服务,不能这个应用域是主控台应用、windows form, IIS, XML web service, 或者是一个windows service

    l 保证全托管代码类型的精确性。而XML web serivces使用soap格式,不支持所有的类型细节。

    l 以引用方式传递对象,并且返回特定应用领域的特定对象。

    l 直接控制对象激活与对象生命周期的管理。

    l 实现和使用第三方通道channel或协议,以扩展通信功能适应你的特殊需求。

    l 直接参与对象通信处理,以实现你需要的功能特性。

    建立两个不同进程中对象之间的平滑通信,是一个普遍性的应用开发需求,尤其是在构建大型分布式应用系统时。具备通信需求的两个不同的进程可以位于一台计算机上,也可以分布于相距遥远的两台计算机上。

    传统上,这要求开发者不仅具备通信对象双方的知识,而且要求具备在底层协议、应用开发接口、配置工具或者文件方面的深厚知识。一句话,这是一项要求具备深厚的技术背景与经验的复杂任务。

    http协议文件下载原理详解

    http协议 文件下载原理详解

    2009年06月01日 星期一 04:53 P.M.

    最近研究了一下关于文件下载的相关内容,觉得还是写些东西记下来比较好。起初只是想研究研究,但后来发现写个可重用性比较高的模块还是很有必要的,我想这也是大多数开发人员的习惯吧。

    对于HTTP协议,向服务器请求某个文件时,只要发送类似如下的请求即可:

    GET /Path/FileName HTTP/1.0

    Host: www.server.com:80

    Accept: */*

    User-Agent: GeneralDownloadApplication

    Connection: close

    每行用一个“回车换行”分隔,末尾再追加一个“回车换行”作为整个请求的结束。

    第一行中的GET是HTTP协议支持的方法之一,方法名是大小写敏感的,HTTP协议还支持OPTIONS、HAED、POST、PUT、DELETE、TRACE、CONNECT等方法,而GET和HEAD这两个方法通常被认为是“安全的”,也就是说任何实现了HTTP协议的服务器程序都会实现这两个方法。对于文件下载功能,GET足矣。GET后面是一个空格,其后紧跟的是要下载的文件从WEB服务器根开始的绝对路径。该路径后又有一个空格,然后是协议名称及协议版本。

    除第一行以外,其余行都是HTTP头的字段部分。Host字段表示主机名和端口号,如果端口号是默认的80则可以不写。Accept字段中的*/*表示接收任何类型的数据。User-Agent表示用户代理,这个字段可有可无,但强烈建议加上,因为它是服务器统计、追踪以及识别客户端的依据。Connection字段中的close表示使用非持久连接。

    关于HTTP协议更多的细节可以参考RFC2616(HTTP 1.1)。因为我只是想通过HTTP协议实现文件下载,所以也只看了一部分,并没有看全。

    如果服务器成功收到该请求,并且没有出现任何错误,则会返回类似下面的数据:

    HTTP/1.0 200 OK

    Content-Length: 13057672

    Content-Type: application/octet-stream

    Last-Modified: Wed, 10 Oct 2005 00:56:34 GMT

    Accept-Ranges: bytes

    ETag: “2f38a6cac7cec51:160c”

    Server: Microsoft-IIS/6.0

    X-Powered-By: ASP.NET

    Date: Wed, 16 Nov 2005 01:57:54 GMT

    Connection: close

    不用逐一解释,很多东西一看几乎就明白了,只说我们大家都关心内容吧。

    第一行是协议名称及版本号,空格后面会有一个三位数的数字,是HTTP协议的响应状态码,200表示成功,OK是对状态码的简短文字描述。状态码共有5类:

    1xx属于通知类;

    2xx属于成功类;

    3xx属于重定向类;

    4xx属于客户端错误类;

    5xx属于服务端错误类。

    对于状态码,相信大家对404应该很熟悉,如果向一个服务器请求一个不存在的文件,就会得到该错误,通常浏览器也会显示类似“HTTP 404 – 未找到文件”这样的错误。Content-Length字段是一个比较重要的字段,它标明了服务器返回数据的长度,这个长度是不包含HTTP头长度的。换句话说,我们的请求中并没有Range字段(后面会说到),表示我们请求的是整个文件,所以Content-Length就是整个文件的大小。其余各字段是一些关于文件和服务器的属性信息。

    这段返回数据同样是以最后一行的结束标志(回车换行)和一个额外的回车换行作为结束,即“\r\n\r\n”。而“\r\n\r\n”后面紧接的就是文件的内容了,这样我们就可以找到“\r\n\r\n”,并从它后面的第一个字节开始,源源不断的读取,再写到文件中了。

    以上就是通过HTTP协议实现文件下载的全过程。但还不能实现断点续传,而实际上断点续传的实现非常简单,只要在请求中加一个Range字段就可以了。

    假如一个文件有1000个字节,那么其范围就是0-999,则:

    Range: bytes=500-      表示读取该文件的500-999字节,共500字节。

    Range: bytes=500-599   表示读取该文件的500-599字节,共100字节。

    Range还有其它几种写法,但上面这两种是最常用的,对于断点续传也足矣了。如果HTTP请求中包含Range字段,那么服务器会返回206(Partial Content),同时HTTP头中也会有一个相应的Content-Range字段,类似下面的格式:

    Content-Range: bytes 500-999/1000

    Content-Range字段说明服务器返回了文件的某个范围及文件的总长度。这时Content-Length字段就不是整个文件的大小了,而是对应文件这个范围的字节数,这一点一定要注意。

    一切好像基本上没有什么问题了,本来我也是这么认为的,但事实并非如此。如果我们请求的文件的URL是类似http://www.server.com/filename.exe这样的文件,则不会有问题。但是很多软件下载网站的文件下载链接都是通过程序重定向的,比如pchome的ACDSee的HTTP下载地址是:

    http://download.pchome.net/php/tdownload2.php sid=5547&url=/multimedia/viewer/acdc31sr1b051007.exe&svr=1&typ=0

    这种地址并没有直接标识文件的位置,而是通过程序进行了重定向。如果向服务器请求这样的URL,服务器就会返回302(Moved Temporarily),意思就是需要重定向,同时在HTTP头中会包含一个Location字段,Location字段的值就是重定向后的目的URL。这时就需要断开当前的连接,而向这个重定向后的服务器发请求。

         好了,原理基本上就是这些了。其实装个Sniffer好好分析一下,很容易就可以分析出来的。不过NetAnts也帮了我一些忙,它的文件下载日志对开发人员还是很有帮助的。

    【转】分析器错误信息:发现不明确的匹配。

    今天又碰到这个错误了,晕啊;难到我又犯低级错误了?

    项目发布了一下,运行时就出错了,错误代码如下:

    说明: 在分析向此请求提供服务所需资源时出错。请检查下列特定分析错误详细信息并适当地修改源文件。

    分析器错误信息: 发现不明确的匹配。

    源错误:

    “/”应用程序中的服务器错误。


    分析器错误

    行 1: <%@ page language="C#" autoeventwireup="true" inherits="web_GovOpen_DepartInfo, App_Web_departinfo.aspx.65a6504e" %>
    行 2: 
    行 3: <%@ Register Src="top.ascx" TagName="top" TagPrefix="uc4" %>

    源文件: /web/govopen/departinfo.aspx 行: 1

    ————-

    这个错误的原因我自然是很清楚,只是不知道为什么它会出这个错。

    估计前一段,要新增功能,我没功夫做,让一个同事帮做了,可能是他在页面中新增的控件id与cs文件中我原有的变量名重名。查看了一下源代码,果然如此;

    今天有空,解释一下这个错误的原因吧。

    在ASP.net中,每个aspx页面都会有一个.cs文件,(好像不可以多个aspx共用一个cs的,我前面就碰到这个问题),在aspx页面中,我们会用到服务器控件,或html控件,这些控件的id命名时,如果与cs文件中的变量重名的话,就会出错;而且不管大小写是否一样,都会报错;

    可能大家会问,C#不是区分大小写的吗?C#是区分大小写的,也正是因为如此,我们在调试时不会报错,而IIS呢,它是不区分大小写的,发布后,就报错了。

    当然,如果你不想改动程序去修正这个错误的话,你也可以将整个项目的源程序复制到IIS目录下,就可以正常运行,呵呵,非常不建议这样做;

    我们写在程序时,虽然C#中,变量string company与string Company会被区分成两个变量;但我们并不提倡这样做,应尽量避免,这个大家一般不会写错;主要是aspx页面中的控件id,id之间也不要用相同的字符,而且与cs文件中变量名也不要采用相同的字符,不仅是区分大小写的问题;

    再有,就是,在程序中,我们写好了一类,如Deparment;而我们在aspx的页面中,放了一个控件,如gridview,其id为department或是Deparment,在cs文件中,我们照样可以Deparment.DataSource,以及Deparment.DataBind()来绑定,都不会报错的;而一旦发布后,到了IIS中,就会报错;

    这些命名方法,虽然不算错误的,但要避免,不要光看调试时报不报错,关键是,项目发布后是否正常运行;我们还要考滤项目发布后的运行环境,就是在IIS下的情况。

    HTTP500错误

    ⑴知道了导致http 500内部错误的原因,解决起来就比较简单了,那就是人工同步iwam账号在active directory、iis metabase数据库和com+应用程序中的密码。
    具体操作分三步,均需要以管理员身份登录计算机以提供足够的操作权限(iwam账号以iwam_myserver为例)。
    (一)更改active directory中iwam_myserver账号的密码
    因iwam账号的密码由系统控制,随机产生,我们并不知道是什么,为完成下面两步的密码同步工作,我们必须将iwam账号的密码设置为一个我们知道的值。
    1、选择“开始”-&gt;“程序”-&gt;“管理工具”-&gt;“active directory用户和计算机“,启动“active directory用户和计算机”管理单元。
    2、单击“user”,选中右面的“iwam_myserver”,右击选择“重设密码(t)…”,在跳出的重设密码对方框中给iwam_myserver设置新的密码,这儿我们设置成“aboutnt2001”(没有引号的),确定,等待密码修改成功。
    (二)同步iis metabase中iwam_myserver账号的密码
    可能因为这项改动太敏感和重要,微软并没有为我们修改iis metabase中iwam_myserver账号密码提供一个显式的用户接口,只随iis5提供了一个管理脚本adsutil.vbs,这个脚本位于c:\inetpub\adminscripts子目录下(位置可能会因你安装iis5时设置的不同而有所变动)。
    adsutil.vbs脚本功能强大,参数非常多且用法复杂,这里只提供使用这个脚本修改iwam_myserver账号密码的方法:
    adsutil set w3svc/wamuserpass password
    “password“参数就是要设置的iwam账号的新的密码。因此我们将iis metabase中iwam_myserver账号的密码修改为“aboutnt2001”的命令就是:
    c:\inetpub\adminscripts&gt;adsutil set w3svc/wamuserpass “ab

     

     

    ⑵http://www.cnblogs.com/wf225/archive/2008/04/30/1178058.html   {***********主要}

     按⑵做完后,会创建一个名为ASPNET的用于运行ASP.NET辅助进程(asp_wp.exe)的帐号。.net会用它来访问数据库,你可以在你建立的数据库上右键-属性-文件里, 把数据库的拥有者改为机器名/ASPNET

    Server Application Error 问题的解决   {************主要}

    解决办法:
    [1]:检查你的DTC服务(全名:Distributed Transaction Coordinator)是否可以正常启动,如果正常的话请你跳过此步骤;如果出错,无法正常启动,请在开始菜单的运行中 运行:msdtc -resetlog      以创建日志文件。重起机器,检查IIS是否可以正常使用,若不行继续。

    [2]:在CMD下执行以下命令:

                    cd %windir%\system32\inetsrv

                    rundll32 wamreg.dll, CreateIISPackage

                    regsvr32 asptxn.dll

    重起机器,我的问题到这步已经可以完美解决!遇到这个郁闷的问题 系统导了一次,IIS重装了若干次,BAIDU了一些资料,终于解决了,希望对你有帮助。

    重要提示(skyaspnet),  如果在些过程中出现 wamreg.dll 出错,  请按以下步骤解决:

    1、恢复MSDTC服务。因为我的服务中没有此项服务,故先行安装:msdtc -install

    2、重建日志文件:msdtc -resetlog

    3、不需要卸载重装IIS,在服务中停止“World Wide Web Publishing”、“IIS Admin”两项服务。

    4、在CMD下执行以下命令:
                    cd %windir%\system32\inetsrv
                    rundll32 wamreg.dll, CreateIISPackage
                    regsvr32 asptxn.dll

    5、启动“IIS Admin”、“World Wide Web Publishing”两项服务。