因胸联盟 发表于 2015-1-16 22:45:49

ASP.NET网页设计保举:ASP.NET假造主机平安毛病办理计划...

我有个同学,他是搞Java的,他给我说“Java不是效率低,而是速度慢。”,我不是搞Java的,我实在想不透这句话的含义,难道执行速度不就是效率低吗?难道执行速度慢还成效率高了?asp.net|平安|平安毛病|办理|假造主机  申明:本文中所需情况为2003Server+iis6.0+mssql2000

  已经很早就在网上看到一篇关于<asp.net假造主机的严重隐患>的文章,事先其实不在乎,做过asp假造主机的伴侣大概都晓得,即对每个用户都设置一个自力的服务器用户和单个目次的操纵权限,可以基础上办理asp的fso成绩。

  在网上偶然中发明了一个叫做webadmin的asp.net-webshell,对本人的服务器举行测试的时分,让我年夜吃一惊,竟然对我服务器的c盘有读取的权限。和对全部硬盘的修正删除权限。如许的话,那末我的服务器的平安……

  为了进一步证明,自己曾在国际一些出名的假造主机供应商上作过测试,均有和我一样的成绩。

  有需要先先容一下毛病的缘故原由。

  ASP中经常使用的尺度组件:FileSystemObject,这个组件为ASP供应了壮大的文件体系会见才能,能够对服务器硬盘上的任何有权限的目次和文件举行读写、删除、更名等操纵。FSO工具来自微软供应的剧本运转库scrrun.dll中。

  在ASP.NET中我们发明这一成绩仍旧存在,而且变得加倍难以办理。这是由于.NET中关于体系IO操纵的功效变得加倍壮大,而使这一成绩更严峻的是ASP.NET所具有的一项新功效,这就组件不必要象ASP那样必需要利用regsvr32来注册了,只需将Dll类库文件上传到bin目次下就能够间接利用了。这一功效的确给开辟ASP.NET带来了很年夜的便利,可是却使我们在ASP中将此dll删除大概更名的办理办法得到功效了,提防此成绩就变得加倍庞大。必要进一步懂得的伴侣能够看<asp.net假造主机的严重隐患>一文,本文就不再反复。只针对此成绩引出假造主机的平安设置。

  网上提出针对此成绩用Microsoft.NETFrameworkConfigration设置System.io的对目次读取的权限,经由我们长工夫的测试没有乐成,多是.netframework1.1机制变革了?

  空话不说。先说说办理的思绪:在IIS6中,Web使用程序的事情历程设置为以历程标识“NetworkService”运转。在IIS5中,历程外Web使用程序则设置为以IWAM_<服务器名>帐户运转,这个帐户是一般的当地用户帐户。

  NetworkService是WindowsServer2003中的内置帐户。懂得IIS5上的当地用户帐户(IUSR和IWAM)与这个内置帐户之间的区分长短常主要的。Windows操纵体系中的一切帐户都分派了一个SID(平安标识,SecurityID)。服务器是依据SID,而不是与SID相干的称号来辨认服务器上一切帐户的,而我们在与用户界面举行交互时,则是利用称号举行交互的。服务器上创立的尽年夜部分帐户都是当地帐户,都具有一个独一的SID,用于标识此帐户从属于该服务器用户数据库的成员。因为SID只是相对服务器是独一的,因而它在任何其他体系上有效。以是,假如您为当地帐户分派了针对某文件或文件夹的NTFS权限,然后将该文件及其权限复制到另外一台盘算机上时,方针盘算机上并没有针对这个迁徙SID的用户帐户,即便其上有一个同名帐户也是云云。这使得包括NTFS权限的内容复制大概呈现成绩。

  内置帐户是由操纵体系创立的、一类较为出格的帐户或组,比方System帐户、NetworkService和Everyone组。这些工具的主要特性之一就是,它们在一切体系上都具有一个不异的、尽人皆知的SID。当将分派了NTFS权限的文件复制到内置帐户时,权限在服务器之间是无效的,由于内置帐户的SID在一切服务器上都是不异的。WindowsServer2003服务中的NetworkService帐户是出格计划的,公用于为使用程序供应会见收集的充足权限,并且在IIS6中,无需提拔权限便可运转Web使用程序。这关于IIS平安性来讲,是一个特年夜的动静,由于不存在缓冲溢出,怀有歹意的使用程序没法破译历程标识,或是对使用程序的打击不克不及进进System用户情况。更加主要的一点是,不再能构成针对System帐户的“后门”,比方,再也没法经由过程InProcessIsapiApps元数据库项使用加载到Inetinfo的使用程序。

  NetworkService帐户在创立时不单单思索了在IIS6中的使用。它还具有历程标识W3WP.exe的尽年夜部分(并非全体)权限。好像ASPNET用户为了运转ASP.net使用程序,必要具有IIS5服务器上某些地位的会见权限,历程标识W3WP.exe也必要具有相似地位的会见权限,并且还必要一些默许情形下没有指派给内置组的权限。

  为了办理的便利,在安装IIS6时创立了IIS_WPG组(也称为IIS事情历程组,IISWorkerProcessGroup),并且它的成员包含LocalSystem(当地体系)、LocalService(当地服务)、NetworkService(收集服务)和IWAM帐户。IIS_WPG的成员具有得当的NTFS权限和需要的用户权限,能够充任IIS6中事情历程的历程标识。

  因而,NetworkService帐户供应了会见上述地位的权限,具有充任IIS6事情历程的历程标识的充分权限,和具有会见收集的权限。

  Msdn上说:在WindowsServer2003中,用户高低文称为NETWORKSERVICE。这些用户帐户是在.NETFramework安装过程当中创立的,它具有独一的不容易破解的暗码,并仅被授与无限的权限。ASPNET或NETWORKSERVICE用户只能会见运转Web使用程序所需的特定文件夹,如Web使用程序存储已编译文件的in目次。

  要将历程标识设置为特定用户名,以代替ASPNET或NETWORKSERVICE用户标识,您供应的用户名和暗码都必需存储在machine.config文件中。

  可是依据实践情形,asp.net的system.io能够无穷制会见不设防的服务器路径。不晓得这算不算一个ms的严重毛病。并且基本不克不及使iis以machine.config的用户实行asp.net程序。J

  怎样办理呢?谜底就是―使用程序池。

  IIS6.0在被称为使用程序断绝形式(断绝形式)的两种分歧操纵形式下运转,它们是:事情历程断绝形式和IIS5.0断绝形式。这两种形式都要依附于HTTP.sys作为超文本传输协定(HTTP)侦听程序;但是,它们外部的事情道理是一模一样的。

  事情历程断绝形式使用IIS6.0的从头计划的系统布局而且利用事情历程的中心组件。IIS5.0断绝形式用于依附IIS5.0的特定功效和举动的使用程序。该断绝形式由IIs5IsolationModeEnabled设置数据库属性指定。

  您所选择的IIS使用程序断绝形式对功能、牢靠性、平安性和功效可用性城市发生影响。事情历程断绝形式是IIS6.0操纵的保举形式,由于它为使用程序供应了更牢靠的平台。事情历程断绝形式也供应了更初级其余平安性,由于运转在事情历程中的使用程序的默许标识为NetworkService。

  以IIS5.0断绝形式运转的使用程序的默许标识为LocalSystem,该标识同意会见并具有变动盘算机上几近一切资本的才能。

IIS功效IIS5.0断绝形式宿主/组件事情历程断绝形式宿主/组件事情历程办理N/ASvchost.exe/WWW服务事情历程N/AW3wp.exe/事情历程运转历程内ISAPI扩大Inetinfo.exeW3wp.exe运转历程外ISAPI扩大DLLHost.exeN/A(一切的ISAPI扩大都在历程内)运转ISAPI选择器Inetinfo.exeW3wp.exeHTTP.sys设置Svchost.exe/WWW服务Svchost.exe/WWW服务HTTP协定撑持Windows内核/HTTP.sysWindows内核/HTTP.sysIIS设置数据库Inetinfo.exeInetinfo.exeFTPInetinfo.exeInetinfo.exeNNTPInetinfo.exeInetinfo.exeSMTPInetinfo.exeInetinfo.exe 
  因而可知,我们只能利用事情历程断绝形式办理.net的平安成绩。
<P>  默许情形下,IIS6.0在事情历程断绝形式下运转,如图五所示。在这类形式中,关于每个Web使用,IIS6.0都用一个自力的w3wp.exe的实例来运转它。w3wp.exe也称为事情历程(WorkerProcess),或W3Core。


  牢靠性和平安性。牢靠性的进步是由于一个Web使用的妨碍不会影响到其他Web使用,也不会影响http.sys,每个Web使用由W3SVC独自地监督其安康情况。平安性的进步是因为使用程序不再象IIS5.0和IIS4.0的历程内使用那样用System帐户运转,默许情形下,w3wp.exe的一切实例都在一个权限无限的“收集服务”帐户下运转,如图六所示,需要时,还能够将事情历程设置成用其他用户帐户运转。


  对,这里,这里就是我们办理的中心。

  我们把每个网站都分派一个自力的使用程序池,并付与分歧的权限。不就可以办理这个成绩了吗?

  详细怎样做呢,上面我就针对创建一个网站来做一个树模:

  起首,我们为网站创立两个用户(一个是app_test_user、暗码为appuser,一个是iis_test_user、暗码为iisuser)

  1.翻开盘算机办理器

  2.单击把持台树中的用户→盘算机办理→体系工具→当地用户和组→用户

  3.单击“操纵”菜单上的“新用户”输出用户名为。app_test_user、暗码为appuser

  4.在对话框中键进得当的信息。

  5.选中复选框:

   用户不克不及变动暗码

   暗码永不外期

  6.单击“创立”,然后单击“封闭”。


  依照此办法在创立iis_test_user账户

  然后分离把app_test_user增加到iis_wpg组,把iis_test_user增加到Guests组。删除其他组。


  然后,创建响应的使用程序池。

  顺次翻开Internet信息服务→当地盘算机→使用程序池→新建→使用程序池

  新建一个名字为test的使用程序池


  编纂test使用程序池的属性→标示→设置→用户名→扫瞄→把用户名改成我们方才创建的app_test_user并输出响应的暗码


  其次创建响应的网站。

  顺次翻开Internet信息服务→当地盘算机→网站→新建→test的网站,目次为d:        est→编纂test网站的属性→主目次→使用程序池→app_test_user→目次平安性→身份考证和会见把持→编纂,选择我们方才创建的iis_test_user,并输出响应的暗码iisuser→保留并加入。


  最初设定服务器的平安。

  C:只给administrators和system完整把持的权力,删撤除其他一切的权限,不交换子目次


  C:DocumentsandSettings承继父项,并交换子目次。

  C:ProgramFiles承继父项,并交换子目次,并把C:ProgramFilesCommonFilesMicrosoftShared承继属性删除并复制现有属性,增添users的读取权限并交换子目次(如许做是为了可以让asp,asp.net利用access等数据库)。

  C:windows删除承继,并复制现有属性,只赐与administrators,system完整把持和users读取的权限并交换子目次。


  其他一切的盘都只给于administrators和system用户的完整把持权限,删除其他一切用户并交换子目次。

  D:        est(用户网站目次)承继现有属性并增添app_test_user和iis_test_user完整把持的权限并交换子目次。

  今后每增添一个网站都以此类推。

  可是,至此,system.io仍是对c:windows又读取权限的,(嫌疑networkservers用户属于users组,可是很多多少服务都要利用users组来实行的,以是不克不及把c:windwos往失落users组的读取权限)但必需晓得体系路径,有两种计划办理。

  1、再安装体系的时分利用无人值守安装,改换c:windows默许安装路径,如变动为c:        esttest(要切合dos的定名划定规矩,不克不及凌驾8个字符)。这个是必须的

  2、以下地位具有指派给IIS_WPG的权限:

  %windir%helpiishelpcommonC读取
  %windir%IISTemporaryCompressedFilesC列出、读取、写进
  %windir%system32inetsrvASPCompiledTemplateC读取
  Inetpubwwwroot(或内容目次)-读取、实行

  别的,IIS_WPG还具有以下用户权限:

  疏忽遍历反省(SeChangeNotifyPrivilege)

  作为批处置功课登录(SeBatchLogonRight)

  从收集会见此盘算机(SeNetworkLogonRight)

  固然两种办法分离起来算是最平安的计划,一样平常利用第一种计划已算是很平安的,究竟是用一个webshell来推测8位字符的目次仍是必要消费工夫的。利用防火墙很简单就可以发觉出来,并加以把持。

  第二种大概依据所安装软件分歧还要响应增添目次的读取权限,具体情形要依据软件来断定。

  假如主机用户对照多,这将是一个相称年夜的休息量,保举利用程序来办理成绩,上面给出网上不罕见的针对iis使用程序池操纵的代码和针对iis假造目次的操纵代码。
  操纵iis使用程序池


usingSystem;
usingSystem.DirectoryServices;
usingSystem.Reflection;

namespaceADSI1
{
 ///
 ///SmallclasscontainingmethodstoconfigureIIS.
 ///
 classConfigIIS
 {
  ///
  ///Themainentrypointfortheapplication.
  ///
  
  //主程序出口,能够选择用哪些,我为了便利,全体功效都写上往了。
  staticvoidMain(string[]args)
  {
   stringAppPoolName="MyAppPool";
   stringnewvdir1="MyVDir";
   DirectoryEntrynewvdir=CreateVDir(newvdir1);

   CreateAppPool(AppPoolName);
   AssignAppPool(newvdir,AppPoolName);

   ConfigAppPool("Stop",AppPoolName);
  }

  //创立假造目次
  staticDirectoryEntryCreateVDir(stringvdirname)
  {
   DirectoryEntrynewvdir;
   DirectoryEntryroot=newDirectoryEntry("IIS://localhost/W3SVC/1/Root");
   newvdir=root.Children.Add(vdirname,"IIsWebVirtualDir");
   newvdir.Properties["Path"]="c:inetpubwwwroot";
   newvdir.Properties["AccessScript"]=true;
   newvdir.CommitChanges();
   returnnewvdir;
  }

  //创立新的使用程序池。
  staticvoidCreateAppPool(stringAppPoolName)
  {
   DirectoryEntrynewpool;
   DirectoryEntryapppools=newDirectoryEntry("IIS://localhost/W3SVC/AppPools");
   newpool=apppools.Children.Add(AppPoolName,"IIsApplicationPool");
   newpool.CommitChanges();
  }

  staticvoidAssignAppPool(DirectoryEntrynewvdir,stringAppPoolName)
  {
   object[]param={0,AppPoolName,true};
   newvdir.Invoke("AppCreate3",param);
  }

  //method是办理使用程序池的办法,有三种Start、Stop、Recycle,而AppPoolName是使用程序池称号
  staticvoidConfigAppPool(stringmethod,stringAppPoolName)
  {
   DirectoryEntryappPool=newDirectoryEntry("IIS://localhost/W3SVC/AppPools");
   DirectoryEntryfindPool=appPool.Children.Find(AppPoolName,IIsApplicationPool");
   findPool.Invoke(method,null);
   appPool.CommitChanges();
   appPool.Close();
  }

  //使用程序池的列表
  staticvoidAppPoolList()
  {
   DirectoryEntryappPool=newDirectoryEntry("IIS://localhost/W3SVC/AppPools");
   foreach(DirectoryEntryainappPool.Children)
   {
    Console.WriteLine(a.Name);
   }
  }

  privatevoidVDirToAppPool()
  {
   DirectroryEntryVD=newDirectoryEntry("IIS://localhost/W3SVC/1/ROOT/ccc");
   Console.WriteLine(VD.Properties["AppPoolId"].Value.ToString());
  }
 }
}

  iis6操纵的例子

usingSystem;
usingSystem.DirectoryServices;
usingSystem.Collections;
usingSystem.Text.RegularExpressions;
usingSystem.Text;

namespaceWuhy.ToolBox
{
 ///</summary>

 publicclassIISAdminLib
 {
  #regionUserName,Password,HostName的界说
  publicstaticstringHostName
  {
   get
   {
    returnhostName;
   }
   set
   {
    hostName=value;
   }
  }

 publicstaticstringUserName
 {
  get
  {
   returnuserName;
  }
  set
  {
   userName=value;
  }
 }

 publicstaticstringPassword
 {
  get
  {
   returnpassword;
  }
  set
  {
   if(UserName.Length<=1)
   {
    thrownewArgumentException("还没有指定好用户名。请先指定用户名");
   }
  password=value;
 }
}

publicstaticvoidRemoteConfig(stringhostName,stringuserName,stringpassword)
{
 HostName=hostName;
 UserName=userName;
 Password=password;
}

privatestaticstringhostName="localhost";
privatestaticstringuserName;
privatestaticstringpassword;
#endregion

#region依据路径机关Entry的办法

///<summary>
///依据是不是有效户名来判别是不是是远程服务器。
///然后再机关出分歧的DirectoryEntry出来
///</summary>
///<paramname="entPath">DirectoryEntry的路径</param>
///<returns>前往的是DirectoryEntry实例</returns>

publicstaticDirectoryEntryGetDirectoryEntry(stringentPath)
{
 DirectoryEntryent;
 if(UserName==null)
 {
  ent=newDirectoryEntry(entPath);
 }
 else
 {
  //ent=newDirectoryEntry(entPath,HostName+""+UserName,Password,AuthenticationTypes.Secure);
  ent=newDirectoryEntry(entPath,UserName,Password,AuthenticationTypes.Secure);
 }
 returnent;
}

#endregion
#region增加,删除网站的办法

///<summary>
///创立一个新的网站。依据传过去的信息举行设置
///</summary>
///<paramname="siteInfo">存储的是新网站的信息</param>

publicstaticvoidCreateNewWebSite(NewWebSiteInfositeInfo)
{
 if(!EnsureNewSiteEnavaible(siteInfo.BindString))
 {
  thrownewDuplicatedWebSiteException("已有了如许的网站了。"+Environment.NewLine+siteInfo.BindString);
 }
 stringentPath=String.Format("IIS://{0}/w3svc",HostName);
 DirectoryEntryrootEntry=GetDirectoryEntry(entPath);
 stringnewSiteNum=GetNewWebSiteID();
 DirectoryEntrynewSiteEntry=rootEntry.Children.Add(newSiteNum,"IIsWebServer");
 newSiteEntry.CommitChanges();
 newSiteEntry.Properties["ServerBindings"].Value=siteInfo.BindString;
 newSiteEntry.Properties["ServerComment"].Value=siteInfo.CommentOfWebSite;
 newSiteEntry.CommitChanges();
 DirectoryEntryvdEntry=newSiteEntry.Children.Add("root","IIsWebVirtualDir");
 vdEntry.CommitChanges();
 vdEntry.Properties["Path"].Value=siteInfo.WebPath;
 vdEntry.CommitChanges();
}

///<summary>
///删除一个网站。依据网站称号删除。
///</summary>
///<paramname="siteName">网站称号</param>

publicstaticvoidDeleteWebSiteByName(stringsiteName)
{
 stringsiteNum=GetWebSiteNum(siteName);
 stringsiteEntPath=String.Format("IIS://{0}/w3svc/{1}",HostName,siteNum);
 DirectoryEntrysiteEntry=GetDirectoryEntry(siteEntPath);
 stringrootPath=String.Format("IIS://{0}/w3svc",HostName);
 DirectoryEntryrootEntry=GetDirectoryEntry(rootPath);
 rootEntry.Children.Remove(siteEntry);
 rootEntry.CommitChanges();
}

#endregion
#regionStart和Stop网站的办法

publicstaticvoidStartWebSite(stringsiteName)
{
 stringsiteNum=GetWebSiteNum(siteName);
 stringsiteEntPath=String.Format("IIS://{0}/w3svc/{1}",HostName,siteNum);
 DirectoryEntrysiteEntry=GetDirectoryEntry(siteEntPath);
 siteEntry.Invoke("Start",newobject[]{});
}

publicstaticvoidStopWebSite(stringsiteName)
{
 stringsiteNum=GetWebSiteNum(siteName);
 stringsiteEntPath=String.Format("IIS://{0}/w3svc/{1}",HostName,siteNum);
 DirectoryEntrysiteEntry=GetDirectoryEntry(siteEntPath);
 siteEntry.Invoke("Stop",newobject[]{});
}

#endregion
#region确认网站是不是不异

///<summary>
///断定一个新的网站与现有的网站没有不异的。
///如许避免将不法的数据寄存到IIS内里往
///</summary>
///<paramname="bindStr">网站邦定信息</param>
///<returns>真为能够创立,假为不成以创立</returns>

publicstaticboolEnsureNewSiteEnavaible(stringbindStr)
{
 stringentPath=String.Format("IIS://{0}/w3svc",HostName);
 DirectoryEntryent=GetDirectoryEntry(entPath);
 foreach(DirectoryEntrychildinent.Children)
 {
  if(child.SchemaClassName=="IIsWebServer")
  {
   if(child.Properties["ServerBindings"].Value!=null)
   {
    if(child.Properties["ServerBindings"].Value.ToString()==bindStr)
    {
     returnfalse;
    }
   }
  }
 }
 returntrue;
}

#endregion
#region猎取一个网站编号的办法
///<summary>
///猎取一个网站的编号。依据网站的ServerBindings大概ServerComment来断定网站编号
///</summary>
///<paramname="siteName"></param>
///<returns>前往网站的编号</returns>
///<exceptioncref="NotFoundWebSiteException">暗示没有找到网站</exception>

publicstaticstringGetWebSiteNum(stringsiteName)
{
 Regexregex=newRegex(siteName);
 stringtmpStr;
 stringentPath=String.Format("IIS://{0}/w3svc",HostName);
 DirectoryEntryent=GetDirectoryEntry(entPath);
 foreach(DirectoryEntrychildinent.Children)
 {
  if(child.SchemaClassName=="IIsWebServer")
  {
   if(child.Properties["ServerBindings"].Value!=null)
   {
    tmpStr=child.Properties["ServerBindings"].Value.ToString();
    if(regex.Match(tmpStr).Success)
    {
     returnchild.Name;
    }
   }
   if(child.Properties["ServerComment"].Value!=null)
   {
    tmpStr=child.Properties["ServerComment"].Value.ToString();
    if(regex.Match(tmpStr).Success)
    {
     returnchild.Name;
    }
   }
  }
 }

 thrownewNotFoundWebSiteException("没有找到我们想要的站点"+siteName);
}

#endregion
#region猎取新网站id的办法
///<summary>
///猎取网站体系内里可使用的最小的ID。
///这是由于每一个网站都必要有一个独一的编号,并且这个编号越小越好。
///这内里的算法经由了测试是没有成绩的。
///</summary>
///<returns>最小的id</returns>

publicstaticstringGetNewWebSiteID()
{
 ArrayListlist=newArrayList();
 stringtmpStr;
 stringentPath=String.Format("IIS://{0}/w3svc",HostName);
 DirectoryEntryent=GetDirectoryEntry(entPath);
 foreach(DirectoryEntrychildinent.Children)
 {
  if(child.SchemaClassName=="IIsWebServer")
  {
   tmpStr=child.Name.ToString();
   list.Add(Convert.ToInt32(tmpStr));
  }
 }
 list.Sort();
 inti=1;
 foreach(intjinlist)
 {
  if(i==j)
  {
   i++;
  }
 }
 returni.ToString();
}
#endregion
}

#region新网站信息布局体

publicstructNewWebSiteInfo
{
 privatestringhostIP;//TheHostsIPAddress
 privatestringportNum;//TheNewWebSitesPort.generallyis"80"
 privatestringdescOfWebSite;//网站暗示。通常是网站的网站名。比方"www.dns.com.cn"
 privatestringcommentOfWebSite;//网站正文。一样平常也为网站的网站名。
 privatestringwebPath;//网站的主目次。比方"e:        mp"
 publicNewWebSiteInfo(stringhostIP,stringportNum,stringdescOfWebSite,stringcommentOfWebSite,stringwebPath)
 {
  this.hostIP=hostIP;
  this.portNum=portNum;
  this.descOfWebSite=descOfWebSite;
  this.commentOfWebSite=commentOfWebSite;
  this.webPath=webPath;
 }
 publicstringBindString
 {
  get
  {
   returnString.Format("{0}:{1}:{2}",hostIP,portNum,descOfWebSite);
  }
 }
 publicstringCommentOfWebSite
 {
  get
  {
   returncommentOfWebSite;
  }
 }
 publicstringWebPath
 {
  get
  {
   returnwebPath;
  }
 }
}
#endregion
}

  至此,一个绝对平安的.net主机就创建起来了,跟着.net2.0的公布愈来愈切近亲近,但愿ms能针对此成绩作一个妥帖的提防。

  我们已复杂的先容了一下ASP.NET中关于文件IO体系的毛病的防治办法,这一办法有些烦琐,可是却能够从基本上根绝一些毛病,我们会商的只是很少的一部分,更多的办理放法必要人人配合来探究、进修。以前很热炒跨平台,主要是由于硅谷挑战微软霸主地位的热情,但是冷静下来后,跨平台往往不是那么一回事。假设你有个软件,所谓的跨平台,你只需要为第二个平台上重新编译一次就行了,这样很难么?

爱飞 发表于 2015-1-24 15:23:32

弱类型造成潜在的出错可能:尽管弱数据类型的编程语言使用起来回方便一些,但相对于它所造成的出错几率是远远得不偿失的。

飘飘悠悠 发表于 2015-2-1 18:36:09

主流网站开发语言之CGI:CGI就是公共网关接口(CommonGatewayInterface)的缩写。它是最早被用来建立动态网站的后台技术。这种技术可以使用各种语言来编写后台程序,例如C,C++,Java,Pascal等。

因胸联盟 发表于 2015-2-7 13:28:23

ASP.Net摆脱了以前ASP使用脚本语言来编程的缺点,理论上可以使用任何编程语言包括C++,VB,JS等等,当然,最合适的编程语言还是MS为.NetFrmaework专门推出的C(读csharp)。

透明 发表于 2015-2-22 00:23:18

有一丝可惜的是,这个系列太强了,Java阵营的朋友根本就是哑口无言...争论之火瞬间被浇灭,这不是我想这么早就看到的,但是值了。

小魔女 发表于 2015-3-6 22:18:22

主流网站开发语言之CGI:CGI就是公共网关接口(CommonGatewayInterface)的缩写。它是最早被用来建立动态网站的后台技术。这种技术可以使用各种语言来编写后台程序,例如C,C++,Java,Pascal等。

灵魂腐蚀 发表于 2015-3-13 22:07:47

是目前ASP在UNIX/Linux上的应用可以说几乎为0)。所以平台的局限性和ASP自身的安全性限制了ASP的广泛应用。

再见西城 发表于 2015-3-20 20:26:24

最强的技术支持WebService,而且有.NET的所有library做后盾。而且ASP.NET在.NET3.5中还有微软专门为AJAX开发的功能--ASP.NETAJAX。
页: [1]
查看完整版本: ASP.NET网页设计保举:ASP.NET假造主机平安毛病办理计划...