2023年3月

有些时候我们写的asp.net应用程序是运行在虚拟主机上。有一些虚拟主机可能是由于安全的考虑,对asp.net做了权限设置,会导致我们的应用程序无法正常运行。

问题现象:
由于某种原因,asp.net不能加载某些dll文件,出现如下错误提示:


Server Error in '/' Application.

--------------------------------------------------------------------------------


Required permissions cannot be acquired.

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.


Exception Details: System.Security.Policy.PolicyException: Required permissions cannot be acquired.


Source Error:


An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.


Stack Trace:



[PolicyException: Required permissions cannot be acquired.]

System.Security.SecurityManager.ResolvePolicy(Evidence evidence, PermissionSet reqdPset, PermissionSet optPset, PermissionSet denyPset, PermissionSet& denied, Boolean checkExecutionPermission) +2738293

System.Security.SecurityManager.ResolvePolicy(Evidence evidence, PermissionSet reqdPset, PermissionSet optPset, PermissionSet denyPset, PermissionSet& denied, Int32& securitySpecialFlags, Boolean checkExecutionPermission) +57


[FileLoadException: Could not load file or assembly 'Microsoft.Practices.ObjectBuilder, Version=1.0.51205.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. Failed to grant minimum permission requests. (Exception from HRESULT: 0x80131417)]

System.Reflection.Assembly.nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, Assembly locationHint, StackCrawlMark& stackMark, Boolean throwOnFileNotFound, Boolean forIntrospection) +0

System.Reflection.Assembly.InternalLoad(AssemblyName assemblyRef, Evidence assemblySecurity, StackCrawlMark& stackMark, Boolean forIntrospection) +211

System.Reflection.Assembly.InternalLoad(String assemblyString, Evidence assemblySecurity, StackCrawlMark& stackMark, Boolean forIntrospection) +141

System.Reflection.Assembly.Load(String assemblyString) +25

System.Web.Configuration.CompilationSection.LoadAssemblyHelper(String assemblyName, Boolean starDirective) +32




问题分析:
根据我的观察,asp.net应用程序直接生成的dll可以正常加载,由asp.net直接调用的外部dll也可以正常加载,但是仅被外部dll引用的其他外部dll不能加载。我的猜想是:由于权限是不完全的,asp.net应用本身生成的dll和直接引用的dll可以通过权限的继承获得权限,而仅被外部dll引用的其他外部dll因为权限的限制不能继承权限,因此出现了权限不足的问题。

问题解决:
通过在我电脑的试验,推测虚拟主机上修改了根web.config(在我电脑上其位置为
C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\CONFIG
)的设置.
默认web.config的权限设置节如下:


<
location
allowOverride
="true"
>


<
system
.web
>


<
securityPolicy
>


<
trustLevel
name
="Full"
policyFile
="internal"

/>


<
trustLevel
name
="High"
policyFile
="web_hightrust.config"

/>


<
trustLevel
name
="Medium"
policyFile
="web_mediumtrust.config"

/>


<
trustLevel
name
="Low"
policyFile
="web_lowtrust.config"

/>


<
trustLevel
name
="Minimal"
policyFile
="web_minimaltrust.config"

/>


</
securityPolicy
>


<
trust
level
="Full"
originUrl
=""

/>


</
system.web
>


</
location
>

推测虚拟主机上修改之后的设置:


<
location
allowOverride
="false"
>


<
system
.web
>


<
securityPolicy
>


<
trustLevel
name
="Full"
policyFile
="internal"

/>


<
trustLevel
name
="High"
policyFile
="web_hightrust.config"

/>


<
trustLevel
name
="Medium"
policyFile
="web_mediumtrust.config"

/>


<
trustLevel
name
="Low"
policyFile
="web_lowtrust.config"

/>


<
trustLevel
name
="Minimal"
policyFile
="web_minimaltrust.config"

/>


</
securityPolicy
>


<
trust
level
="High"
originUrl
=""

/>


</
system.web
>


</
location
>

他首先设置了
allowOverride
为false,这就阻止了在用户web.config中重新定义权限的能力。然后,他定义trust level为High,而不是默认的Full。经我测试,只要trust level不为Full,仅被外部dll引用的其他外部dll就不能被加载。 因此,我建议技术支持将
allowOverride
节设置为true。这样我就可以在web.config中重新指定权限了。
例:<trust level="Full" originUrl="" />

最近已经不研究aps.net了,因此也没有认真去查找深层的原因,或许我的认识还有误。希望那位高手可以道出深层的原因,或指正我的错误。

阅读msdn,你会读到下面一段:

The CoCreateInstance helper function provides a convenient shortcut by connecting to the class object associated with the specified CLSID, creating an uninitialized instance, and releasing the class object. As such, it encapsulates the following functionality:


CoGetClassObject(rclsid, dwClsContext, NULL, IID_IClassFactory,
&
pCF);

hresult

=
pCF
->
CreateInstance(pUnkOuter, riid, ppvObj) ;

pCF

->
Release();


因此,你会认为CoCreateInstance实际上就是上面一段代码的封装。但是实际上,你错了。你没有留意到在这篇文章的开头的一句话:

Creates a single uninitialized object of the class associated with a specified CLSID. Call CoCreateInstance when you want to create only one object on the local system.

这句话指明,在你希望系统只保存一个COM实例的时候使用此方法。那么CoCreateInstance是怎么做到这一点的呢?上面那三句话可以做到这一点吗?不能。一般情况下,每次调用CreateInstance时,都会创建一个实例。如果CoCreateInstance要保证只有一个实例,则COM库必须在第一次请求的时候保存一个接口引用。每次返回的接口,实际上都是调用下面的代码实现的:


pIUnknown
->
QueryInterface(riid,
void

**
ppvObeject);


总结一下,调用CoCreateInstance实际上会做如下处理:
1、第一次使用CoCreateInstance时,此函数创建一个实例,并请求得到指定的接口引用,并保留此引用。然后调用QueryInterface方法返回请求的接口。
2、再次调用CoCreateInstance时,直接使用QueryInterface方法返回请求的接口,而不再生成新的COM实例。

以上是我做了很多次试验后的推测,并不保证正确。

一、如何设置int型的主键字段自增长?
现在得到了答案:设置此字段为主键并只设置get属性
但是对于我现在的要求,这个还不能满足,或者我的设计不合理。下面说明我的设计。

如图所示,Linkman为Apply和Course共用,因此我没有设置包含(contain)关系,而是使用反向引用(FkReverseQuery)。但是Linkman本身独立存在是没有意义的,所以并没有设计独立的Service类,而是作为Apply和Course的属性随他们保存时保存。由于是反向引用,所以Apply和Course分别保存有一个LinkmanID的属性,在Apply或Course创建的时候,首先创建保存Linkman,获得Linkman在数据库中的ID并设置其属性,然后保存Apply或Course自身。因此,按照这个设计,我必须让Linkman的主键ID自增长,也需要其可以设置。现在NBear版本中我不知道如何做到。

二、如何使用事务?
这也是上面的设计衍生出来的需求。我在保存的时候需要保证Linkman与Apply同时成功或者同时失败。看到NBear有事务功能,但是没有看到任何示例代码或者说明,所以希望可以得到指点。

诸如如下代码:
客户端:

function
initMyAjax() {

var
condpart
=

new
Sys.UI.TextBox($('condpart'));

var
iscond
=

new
Sys.UI.CheckBox($('iscond'));
}

xml-script:

<
script type
=
"
text/xml-script
"
>


<
page xmlns
=
"
http://schemas.microsoft.com/xml-script/2005
"
>


<
components
>


<
Control id
=
"
condpart
"
visibilityMode
=
"
Collapse
"
>


<
bindings
>


<
binding dataContext
=
"
iscond
"
dataPath
=
"
checked
"
property
=
"
visible
"

/>


</
bindings
>


</
Control
>


<
CheckBox id
=
"
iscond
"

/>


</
components
>


</
page
>


</
script
>

怎么在我的机器上都无法运行?
客户端代码提示没有
Sys.UI.TextBox构造函数,但是
Sys.UI.Control是存在并且可以构造成功的
,xml-script直接就不运行,郁闷啊。莫非atlas CTP版本到atlas 1.0的改动去掉了这些?这改动也太大了吧。希望高手指点。
我安装了ASP.NET 2.0 AJAX Extensions 1.0,ASP.NET AJAX Control Toolkit和ASP.NET Futures (July 2007)。