自定义ASP.NET的角色管理

尽管当初安装VS2005的时候没有一同安装SQLExpress版的数据库,在C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\CONFIG下的machine.config文件中的<connectionStrings>依然为SQLExpress的连接字符串,所以,当我采用了SQL2005企业版的数据库来做角色管理的时候,连接出错。这时把这里的连接字符串改为目前连接的数据库连接字符串即可。

另外,在应用程序(网站)的根目录下的web.config文件中加入以下两部分内容(红色部分):

<connectionStrings>
    <add name=”MyConnectionString” connectionString=”Data Source=你的连接字符串;Integrated Security=True”
      providerName=”System.Data.SqlClient” />
    <add name=”SqlServices” connectionString=”你的连接字符串;Integrated Security=True” providerName=”System.Data.SqlClient” />
  </connectionStrings>

<roleManager enabled=”true” cacheRolesInCookie=”true” cookieName=”.ASPROLES”>
        <providers>
          <add connectionStringName=”SqlServices” applicationName=”MyApplication”
               name=”SqlProvider” type=”System.Web.Security.SqlRoleProvider” />
         
        </providers>
      </roleManager>

如此即可。

参考:

1。ASP.NET 2.0 中的新增服务、控件与功能概述

2。在ASP.NET 2.0中配置 AspNetSqlMembershipProvider(AspNetSqlProvider )

2。在ASP.NET 2.0中配置 AspNetSqlMembershipProvider(AspNetSqlProvider )

DataGrid的自动编号问题

序号 内容
1 Taye
2 BOx
3 Glass
4 StarCraf

一、正序

A、AllowPaging=False情况下

<asp:DataGrid id=”DataGrid1″ runat=”server”>
<Columns>
<asp:TemplateColumn>
<ItemTemplate>
<%# Container.ItemIndex + 1%>
</ItemTemplate>
</asp:TemplateColumn>
</Columns>
</asp:DataGrid>

就可以实现

不过更有趣的方法是使用这个方法

<asp:DataGrid id=”DataGrid1″ runat=”server”>
<Columns>
<asp:TemplateColumn>
<ItemTemplate>
<%# this.DataGrid1.Items.Count + 1%>
</ItemTemplate>
</asp:TemplateColumn>
</Columns>
</asp:DataGrid>

也许有些人会觉得很奇怪为什么Items.Count会这样,而不是出来全部总合..但如果你了解绑定的过程时就容易理解.
[从上面来看就是在ItemCreated事件中进行绑定所以得到的Items.Count刚好是当前的序号]

B、AllowPaging=”True”下

如果你DataGrid支持分页则可以如下

<asp:DataGrid id=”DataGrid1″ runat=”server” AllowPaging=”True”>
<Columns>
<asp:TemplateColumn>
<ItemTemplate>
<%# this.DataGrid1.CurrentPageIndex * this.DataGrid1.PageSize + Container.ItemIndex + 1%>
</ItemTemplate>
</asp:TemplateColumn>
</Columns>
</asp:DataGrid>

二、倒序的方法

序号 内容
4 Taye
3 BOx
2 Glass
1 StarCraft

由上面可以知道使用
this.DataGrid1.Items.Count – Container.ItemIndex + 1方法是不可能实现的,得到值而且全会为1
分页的情况下更是一样.所以一开始我们就要取得数据源的行数

.cs

private int rowscount = 0;
protected int RowsCount
{
get{ return rowscount;}
set{ this.rowscount = value; }
}

private void Page_Load(object sender, System.EventArgs e)
{
// 在此处放置用户代码以初始化页面
if(!IsPostBack)
this.BindData();
}

private void BindData()
{
SqlConnection cn = new SqlConnection(“server=(local);database=NorthWind;uid=sa;pwd=”);
string str=@”SELECT Employees.EmployeeID, Orders.EmployeeID
FROM Employees INNER JOIN
Orders ON Employees.EmployeeID = Orders.EmployeeID “;

SqlDataAdapter sqlda = new SqlDataAdapter(str,cn);
DataSet ds = new DataSet();

sqlda.Fill(ds);

this.RowsCount = ds.Tables[0].Rows.Count;

this.DataGrid1.DataSource = ds;
this.DataGrid1.DataBind();

}

.aspx

<asp:DataGrid id=”DataGrid1″ runat=”server” AllowPaging=”True”>
<Columns>
<asp:TemplateColumn>
<ItemTemplate>
<%# RowsCount – DataGrid1.CurrentPageIndex * DataGrid1.PageSize – Container.ItemIndex %>
</ItemTemplate>
</asp:TemplateColumn>
</Columns>
</asp:DataGrid>

当然如果是不是分页的情况一下更容易实现了.

转自:http://blog.csdn.net/mike1983/archive/2006/06/27/841725.aspx

续上篇

4.\App_GlobalResources Folder

资源文件(.resx) 是一个在你的应用程序中依据不同文化来改变页面内容的可以作为数据字典的字串表。除字串外,还可添加image等其它文件。
例如添加两个资源文件到此文件夹:
第一个资源文件是Resource.resx这是默认语言使用英语。
  Name     Value
  Answer     Hello there
  PageTitle    Sample Page
  Question    What is your name?
第二个资源文件是Resource.zh-cn.resx)使用中文。
  Name     Value
  Answer     你好
  PageTitle    示例页面
  Question     你的名字叫什么?

Listing 3-18: A simple ASP.NET page that uses resource files
VB

<%@ Page Language=”VB” Culture=Auto” UICulture=Auto” %>
<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.1//EN”
“http:
//www.w3.org/TR/xhtml11/DTD/xhtml11.dtd”>
<script runat=”server”>
Protected Sub Page_Load()Sub Page_Load(ByVal sender As Object, _
ByVal e As System.EventArgs)
Page.Title 
= Resources.Resource.PageTitle
End Sub

Protected Sub Button1_Click()Sub Button1_Click(ByVal sender As Object, _
ByVal e As System.EventArgs)
Label1.Text 
= Resources.Resource.Answer & “ “ & Textbox1.Text
End Sub

</script>
<html xmlns=”http://www.w3.org/1999/xhtml” >
<head id=”Head1” runat=”server”>
<title></title>
</head>
<body>
<form id=”Form1” runat=”server”>
<p><%= Resources.Resource.Question %></p><br />
<asp:TextBox ID=”Textbox1” Runat=”server”></asp:TextBox><br />
<asp:Button ID=”Button1” Runat=”server” Text=”Submit”
OnClick
=”Button1_Click” />
<p><asp:Label ID=”Label1” Runat=”server”></asp:Label></p>
</form>
</body>
</html>
c#

<%@ Page Language=”C#” Culture=”Auto” UICulture=”Auto” %>
<!DOCTYPE html PUBLIC “//W3C//DTD XHTML 1.1//EN”
“http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd”>
<script runat=”server”>
protected void Page_Load(object sender, System.EventArgs e)
{
Page.Title 
= Resources.Resource.PageTitle;
}

protected void Button1_Click(object sender, System.EventArgs e)
{
Label1.Text 
= Resources.Resource.Answer + “ “ + Textbox1.Text;
}

</script>

当这个程序运行时,会根据浏览器语言设定而选择使用不同的资源文件。如果语言设定为中文则会显示中文,否则为显示默认英文。

5.\App_LocalResources Folder
你也可以把资源文件添加到\App_LocalResources文件夹,只不过\App_GlobalResources文件夹是应用程序级别,而\App_LocalResources文件夹是页面级别。

6.\App_WebReferences Folder
你可以使用\App_WebReferences文件夹自动访在你的应用程序中引用的远程Web services。

7.\App_Browsers Folder
存贮在 \App_Browsers文件夹中的.browser文件,你也可以在\Windows\Microsoft.NET\Framework\v2.0xxxxx\
CONFIG\Browsers文件夹中看得到它,它主要是用来判断浏览器的兼容性的。

转自:http://www.cnblogs.com/zhhui/archive/2006/03/21/354545.html

Professional ASP.NET 2.0之应用程序文件夹-Application Folders

1.\App_Code Folder
  \App_Code文件夹是存贮classes,.wsdl文件和typed datasets的地方。你的解决方案中的所有页面可以自动访问存贮在这个文件夹的任何一个项目。如果这些项目是一个class (.vb or .cs),则Visual Studio 2005会自动检测并编译它;也会自动地创建源于.wsdl文件的XML Web service proxy class;或者一个源于.xsd文件的一个typed dataset。
  下面看一个在你解决方案中使用\App_Code文件夹的简单class的例子:
首先在\App_Code文件夹中建立一个Calculator.vb 或 Calculator.cs文件,如下所示:

Listing 3-14: The Calculator class
VB

Imports Microsoft.VisualBasic
Public Class CalculatorClass Calculator
Public Function Add()Function Add(ByVal a As IntegerByVal b As IntegerAs Integer
Return (a + b)
End Function

End Class
C#

using System;
public class Calculator
{
public int Add(int a, int b)
{
return (a + b);
}

}
其次是对这个class的使用,看下面的一个简单的.aspx文件:
Listing 3-15: An .aspx page that uses the Calculator class
VB

<%@ Page Language=”VB” %>
<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.1//EN”
“http:
//www.w3.org/TR/xhtml11/DTD/xhtml11.dtd”>
<script runat=”server”>
Protected Sub Page_Load()Sub Page_Load(ByVal sender As ObjectByVal e As System.EventArgs)
Dim myCalc As New Calculator
Label1.Text 
= myCalc.Add(1212)
End Sub

</script>
c#

<%@ Page Language=”C#” %>
<!DOCTYPE html PUBLIC “//W3C//DTD XHTML 1.1//EN”
“http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd”>
<script runat=”server”>
protected void Page_Load(object sender, System.EventArgs e)
{
Calculator myCalc 
= new Calculator();
Label1.Text 
= myCalc.Add(1212).ToString();
}

</script>
那么如何在\App_Code文件夹使用两个不同语言的class呢?
首先在\App_Code文件夹中添加两个子文件夹:一个 \VB 文件夹和一个 \CS 文件夹。
\App_Code
  \VB
    Add.vb
  \CS
    Subtract.cs
其次修改web.config文件如下:
Listing 3-17: Structuring the web.config file so that classes in the \App_Code folder can use different languages
<compilation>
  <codeSubDirectories>
    <add directoryName=”VB”></add>
    <add directoryName=”CS”></add>
  </codeSubDirectories>
</compilation>

2.\App_Data Folder
\App_Data文件夹是应用程序存贮数据的地方,可以包括Microsoft SQL Express 文件(.mdf files), Microsoft Access 文件(.mdb files), XML 文件等。

3.\App_Themes Folder

\App_Themes文件夹是存贮asp.net 2.0新特性主题需要使用的 .skin 文件, CSS文件和images文件的地方。

asp.net中使用基于角色role的Forms验证

asp.net中使用基于角色role的Forms验证,大致经过几下四步:
1.配置系统web.config

<system.web> 
<authentication mode=”Forms” > 
 
<forms name=”.yaoCookies” loginUrl=”/duan/Manage/login.aspx” protection=”All”
  timeout
=”20″ path=”/” />
 
</authentication>
</system.web>

其中<authentication mode= “forms”> 表示本应用程序采用Forms验证方式。
1). <forms>标签中的name表示指定要用于身份验证的 HTTP Cookie。默认情况下,name 的值是 .ASPXAUTH。采用此种方式验证用户后,以此用户的信息建立一个FormsAuthenticationTicket类型的身份验证票,再加密序列化为一个字符串,最后将这个字符串写到客户端的name指定名字的Cookie中.一旦这个Cookie写到客户端后,此用户再次访问这个web应用时会将连同Cookie一起发送到服务端,服务端将会知道此用户是已经验证过的.

2). <forms>标签中的loginUrl指定如果没有找到任何有效的身份验证 Cookie,为登录将请求重定向到的 URL。默认值为 default.aspx。loginUrl指定的页面就是用来验证用户身份的,一般此页面提供用户输入用户名和密码,用户提交后由程序来根据自己的需要来验证用户的合法性(大多情况是将用户输入信息同数据库中的用户表进行比较),如果验证用户有效,则生成同此用户对应的身份验证票,写到客户端的Cookie,最后将浏览器重定向到用户初试请求的页面.一般是用FormsAuthentication.RedirectFromLoginPage 方法来完成生成身份验证票,写回客户端,浏览器重定向等一系列的动作.

public static void RedirectFromLoginPage( string userName, bool createPersistentCookie, string strCookiePath );

其中:
userName: 就是此用户的标示,用来标志此用户的唯一标示,不一定要映射到用户账户名称.
createPersistentCookie: 标示是否发出持久的 Cookie。
若不是持久Cookie,Cookie的有效期Expiration属性有当前时间加上web.config中timeout的时间,每次请求页面时,在验证身份过程中,会判断是否过了有效期的一半,要是的话更新一次cookie的有效期;若是持久cookie,Expiration属性无意义,这时身份验证票的有效期有cookie的Expires决定,RedirectFromLoginPage方法给Expires属性设定的是50年有效期。
strCookiePath: 标示将生成的Cookie的写到客户端的路径,身份验证票中保存这个路径是在刷新身份验证票Cookie时使用(这也是生成Cookie的Path),若没有strCookiePath 参数,则使用web.config中 path属性的设置。

这里可以看到,此方法参数只有三个,而身份验证票的属性有七个,不足的四个参数是这么来的:
IssueDate:Cookie发出时间由当前时间得出,
Expiration:过期时间由当前时间和<forms>标签中的timeout参数算出。此参数对非持久性cookie有意义。
UserData:这个属性可以用应用程序写入一些用户定义的数据,此方法没有用到这个属性,只是简单的将此属性置为空字符串,请注意此属性,在后面我们将要使用到这个属性。
Version: 版本号由系统自动提供。

RedirectFromLoginPage方法生成生成身份验证票后,会调用FormsAuthentication.Encrypt 方法,将身份验证票加密为字符串,这个字符串将会是以.ASPXAUTH为名字的一个Cookie的值。
这个Cookie的其它属性的生成:
Domain,Path属性为确省值,Expires视createPersistentCookie参数而定,若是持久cookie,Expires设为50年以后过期;若是非持久cookie,Expires属性不设置。
生成身份验证Cookie后,将此Cookie加入到Response.Cookies中,等待发送到客户端。
最后RedirectFromLoginPage方法调用FormsAuthentication.GetRedirectUrl 方法获取到用户原先请求的页面,重定向到这个页面。

3). <forms>标签中的timeout和path,是提供了身份验证票写入到Cookie过期时间和默认路径。

以上就是基于Forms身份验证的过程,它完成了对用户身份的确认。

2.在受保护的文件夹如Manage下创建一web.config文件,内容如

<configuration>
  <!–指定对整个Manage目录的访问权限–>
  
<system.web>
    
<authorization>
           <!–多个角色用,分隔–>
          
<allow roles=”admin,user”/>
           
<deny users=”*” />
      
</authorization>
  
</system.web>

  
<!–也可控制某个页的权限

  <location path=”AnnounceList.aspx”>
     <system.web>
        <authorization>
           <allow roles=”admin”/>
           <deny users=”*” />
        </authorization>
     </system.web>
  </location>

  <location path=”ConfigInfo.aspx”>
     <system.web>
        <authorization>
           <allow roles=”users”/>
           <deny users=”*” />
        </authorization>
     </system.web>
  </location>

  –>
</configuration>

注:此配置内容也可以加入到系统的web.config文件中,注意加入位置:

……..
    </system.web>

    <location path=”Manage/AnnounceList.aspx”>
    
<system.web>
     
<authorization>
      
<allow roles=”admin”/>
      
<deny users=”*” />
     
</authorization>
     
</system.web>
    </location>

</configuration>

<allow>标签表示允许访问,其中的属性
1). users:一个逗号分隔的用户名列表,这些用户名已被授予对资源的访问权限。问号 (?) 允许匿名用户;星号 (*) 允许所有用户。
2). roles:一个逗号分隔的角色列表,这些角色已被授予对资源的访问权限。
3). verbs:一个逗号分隔的 HTTP 传输方法列表,这些 HTTP 传输方法已被授予对资源的访问权限。注册到 ASP.NET 的谓词为 GET、HEAD、POST 和 DEBUG。

<deny>标签表示不允许访问。其中的属性同上面的。

在运行时,授权模块迭代通过 <allow> 和 <deny> 标记,直到它找到适合特定用户的第一个访问规则。然后,它根据找到的第一项访问规则是 <allow> 还是 <deny> 规则来允许或拒绝对 URL 资源的访问。Machine.config 文件中的默认身份验证规则是 <allow users=”*”/>,因此除非另行配置,否则在默认情况下会允许访问。

那么这些user 和roles又是如何得到的呢?下面看一下授权的详细过程:

1). 一旦一个用户访问这个网站,就行登录确认了身份,身份验证票的cookie也写到了客户端。之后,这个用户再次申请这个web的页面,身份验证票的cookie就会发送到服务端。在服务端,asp.net为每一个http请求都分配一个HttpApplication对象来处理这个请求,在HttpApplication.AuthenticateRequest事件后,安全模块已建立用户标识,就是此用户的身份在web端已经建立起来,这个身份完全是由客户端发送回来的身份验证票的cookie建立的。
2). 用户身份在HttpContext.User 属性中,在页面中可以通过Page.Context 来获取同这个页面相关的HttpContext对象。对于Forms验证,HttpContext.User属性是一个GenericPrincipal类型的对象,GenericPrincipal只有一个公开的属性Identity,有个私有的m_role属性,是string[]类型,存放此用户是属于哪些role的数组,还有一个公开的方法IsInRole(string role),来判断此用户是否属于某个角色。
由于身份验证票的cookie中根本没有提供role这个属性,就是说Forms身份验证票没有提供此用户的role信息,所以,对于Forms验证,在服务端得到的GenericPrincipal 用户对象的m_role属性永远是空的。
3). GenericPrincipal. Identity 属性是一个FormsIdentity类型的对象,这个对象有个Name属性,就是此用户的标示,访问授权就是将此属性做为user来进行授权验证的。FormsIdentity还有一个属性,就是Ticket属性,此属性是身份验证票FormsAuthenticationTicket类型,就是之前服务器写到客户端的身份验证票。
服务器在获取到身份验证票FormsAuthenticationTicket对象后,查看这个身份验证票是不是非持久的身份验证,是的话要根据web.config中timeout属性设置的有效期来更新这个身份验证票的cookie(为避免危及性能,在经过了超过一半的指定时间后更新该 Cookie。这可能导致精确性上的损失。持久性 Cookie 不超时。)
4). 在HttpApplication.ResolveRequestCache事件之前,asp.net开始取得用户请求的页面,建立HttpHandler控制点。这就意味着,在HttpApplication.ResolveRequestCache事件要对用户访问权限就行验证,看此用户或角色是否有权限访问这个页面,之后在这个请求的生命周期内再改变此用户的身份或角色就没有意义了。

以上是Forms验证的全过程,可以看出,这个Forms验证是基于用户的,没有为角色的验证提供直接支持。身份验证票FormsAuthenticationTicket 中的Name属性是用户标示,其实还有一个属性UserData,这个属性可以由应用程序来写入自定义的一些数据,我们可以利用这个字段来存放role的信息,从而达到基于角色验证的目的。

3.登录页

//登录按钮
private void Button1_Click(object sender, System.EventArgs e)
{
            //实体类AdminUserVO对应AdminUser用户表。
            AdminUserVO adminUserVO 
= new AdminUserVO();

            adminUserVO.Uname = UserName.Text.Trim();
            adminUserVO.Upwd 
= UserPwd.Text.Trim();
            adminUserVO.LastIP 
= HttpContext.Current.Request.UserHostAddress;
            adminUserVO.LastTime 
= DateTime.Now;

            bool flag = (new LoginDAO()).Chk(adminUserVO);

            if (flag)
            {
                
//非角色验证时可以用这句:
                
//System.Web.Security.FormsAuthentication.SetAuthCookie(UserName.Text.Trim(),false);

                //创建角色验证信息,把role信息写入到UserData中
                SetLoginCookie(adminUserVO,adminUserVO.Roles.ToLower());

                HttpContext.Current.Response.Redirect(
Main.aspx);
            }
            
else
            {
                HttpContext.Current.Response.Write(
登录失败);
            }
}

//SetLoginCookie方法
public static void SetLoginCookie(AdminUserVO u, string roles)
  {
   
//建立身份验证票对象
   FormsAuthenticationTicket ticket = new FormsAuthenticationTicket (1,u.Uname, DateTime.Now, DateTime.Now.AddMinutes(30), false,roles,/);
   
//加密序列化验证票为字符串
   string hashTicket = FormsAuthentication.Encrypt (ticket) ;
   HttpCookie userCookie 
= new HttpCookie(FormsAuthentication.FormsCookieName, hashTicket);
   HttpContext.Current.Response.Cookies.Add(userCookie);
  }

FormsAuthenticationTicket参数说明:
FormsAuthenticationTicket(
int version, //设为1,版本号由系统自动提供
string name, //用户标示,获取与身份验证 Cookie 关联的用户名
DateTime issueDate, //Cookie 的发出时间, 设置为 DateTime.Now
DateTime expiration, //获取 Cookie 过期的日期/时间
bool isPersistent, //是否持久性(根据需要设置,若是设置为持久性,在发出cookie时,cookie的Expires设置一定要设置),如果已发出持久的 Cookie,则返回 true。否则,身份验证 Cookie 将限制在浏览器生命周期范围内。
string userData, //获取存储在 Cookie 中的应用程序定义字符串,这里用上面准备好的用逗号分割的role字符串
string cookiePath // 返回发出 Cookie 的路径。注意,窗体的路径设置为”/”,这要同发出cookie的路径一致,因为刷新cookie要用这个路径。由于窗体区分大小写,这是为了防止站点中的 URL 的大小写不一致而采取的一种保护措施。
);

4.Global.asax.cs

protected void Application_AuthenticateRequest(Object sender, EventArgs e)
  {
   HttpApplication app 
= (HttpApplication) sender;  
   HttpContext ctx 
= app.Context ; //获取本次Http请求的HttpContext对象  
   if (ctx.User != null)
   {
    
if (ctx.Request.IsAuthenticated == true//验证过的一般用户才能进行角色验证  
    {  
     System.Web.Security.FormsIdentity fi 
= (System.Web.Security.FormsIdentity)ctx.User.Identity ;  
     System.Web.Security.FormsAuthenticationTicket ticket 
= fi.Ticket ; //取得身份验证票  
     string userData = ticket.UserData;//从UserData中恢复role信息
     
string[] roles = userData.Split (,) ; //将角色数据转成字符串数组,得到相关的角色信息  
     ctx.User 
= new System.Security.Principal.GenericPrincipal (fi, roles) ; //这样当前用户就拥有角色信息了
    } 
   }
  }

注:如果使用HttpModule的话,此处代码应该加入在AuthenticateRequest事件中。

转自:http://www.cnblogs.com/yao/archive/2006/06/24/434783.html

ASP.NET视图状态验证MAC失败

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


验证视图状态 MAC 失败。如果此应用程序由网络场或群集承载,请确保 <machineKey> 配置指定了相同的 validationKey 和验证算法。不能在群集中使用 AutoGenerate。

说明: 执行当前 Web 请求期间,出现未处理的异常。请检查堆栈跟踪信息,以了解有关该错误以及代码中导致错误的出处的详细信息。

异常详细信息: System.Web.HttpException: 验证视图状态 MAC 失败。如果此应用程序由网络场或群集承载,请确保 <machineKey> 配置指定了相同的 validationKey 和验证算法。不能在群集中使用 AutoGenerate。

源错误:

只有在调试模式下进行编译时,生成此未处理异常的源代码才会显示出来。若要启用此功能,请执行以下步骤之一,然后请求 URL:

1. 在产生错误的文件的顶部添加一条“Debug=true”指令。例如:

  <%@ Page Language="C#" Debug="true" %>

或:

2. 将以下的节添加到应用程序的配置文件中:

<configuration>
   <system.web>
       <compilation debug="true"/>
   </system.web>
</configuration>

请注意,第二个步骤将使给定应用程序中的所有文件在调试模式下进行编译;第一个步骤仅使该特定文件在调试模式下进行编译。

重要事项: 以调试模式运行应用程序一定会产生内存/性能系统开销。在部署到生产方案之前,应确保应用程序调试已禁用。

堆栈跟踪:

[HttpException (0x80004005): 无法验证数据。]
System.Web.Configuration.MachineKeySection.GetDecodedData(Byte[] buf, Byte[] modifier, Int32 start, Int32 length, Int32& dataLength) +2546764
System.Web.UI.ObjectStateFormatter.Deserialize(String inputString) +214

[ViewStateException: 无效的视图状态。
Client IP: 127.0.0.1
Port: 1678
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)
ViewState: +DHKNyze8Q6fZlW8T3kqrOkcvI1Y6qlhKi0bcpHnBmZdO7ftgMjL4U8x0qsEdbVEp1FmjzezRsCnvvvwXObQqhrwVRRTCc1IAwzNbZeKE3qjqSDfHk3HmK6xBgHm1sTsmWj/0KFgL6qwstm3dOjvGIHahto1iI3T4lH6YU+tjyEms7Fxdv8JZgkux2ghCHWGOmfTVM7C+audblvkaTrfRRlruUsmC1EApq0uAn72UsyW5k9ZdRESK8oZXJsF0149LXunb4FC/bQ96YxtVGE9sQEpZC6mVWBN6/1yK6cuI/sKaNz+ObMvILwEO4uCEKIY4eIRfcIYSG5x9gPTczsWGCfpr7vUTo8FSsXcA/hFkazRtI2MUiCRXo05ISKKhgxpRSYcm50cvpOKryPsre0hxe6Nr5fT17LFm0Y7BmZbh4zEM925/LBwgXRb8aOIMJxkTxIFk787JPF/JBMYZzmoXLacAko5/pUv/M6Cliy3vE4ex0PK5avyPbepMllTtOvfYvmiYCARrElK2zNV3836FEY9k+9898tBijFDCjpDZvXAxNsWFcdYFpUAS+w5elGBmtSIqVJlz7aQikjR9LePHmvKwTCsUjRAGjhFqu+3wa8nj64ySYTL1LYK+YL+dDaQlPF9MT1FQjHnnmHuLdtRIfnZXbv3O0l4biN5eY4Rmovq9ATRjxYcfRN0yw8sf1Gpm29IGO4VZCyJ0xWd4SyOoYrKcq4AVIRK21drbjRQuEKp9BwAgka8xTltFtLTCCKoUZmMbdvxfS233lrEdEGQBg7Dyczt1McCmxkHyI7FOPWIKB16ZCJIG7fVxW3pOFAwL4u8g271kC2o+xERTXCZFjBX9bkwD9...]

[HttpException (0x80004005): 验证视图状态 MAC 失败。如果此应用程序由网络场或群集承载,请确保 配置指定了相同的 validationKey 和验证算法。不能在群集中使用 AutoGenerate。]
System.Web.UI.ViewStateException.ThrowError(Exception inner, String persistedState, String errorPageMessage, Boolean macValidationError) +116
System.Web.UI.ObjectStateFormatter.Deserialize(String inputString) +251
System.Web.UI.ObjectStateFormatter.System.Web.UI.IStateFormatter.Deserialize(String serializedState) +4
System.Web.UI.Util.DeserializeWithAssert(IStateFormatter formatter, String serializedState) +37
System.Web.UI.HiddenFieldPageStatePersister.Load() +220
System.Web.UI.Page.LoadPageStateFromPersistenceMedium() +83
System.Web.UI.Page.LoadAllState() +35
System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +6953
System.Web.UI.Page.ProcessRequest(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +154
System.Web.UI.Page.ProcessRequest() +86
System.Web.UI.Page.ProcessRequestWithNoAssert(HttpContext context) +18
System.Web.UI.Page.ProcessRequest(HttpContext context) +49
ASP.offer_aspx.ProcessRequest(HttpContext context) +29
System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +154
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +64


版本信息: Microsoft .NET Framework 版本:2.0.50727.42; ASP.NET 版本:2.0.50727.42

.net文件上传代码实例

<%@ Import Namespace=”System.IO” %>
<%@ page Language=”C#” debug=”true” %>
<html>
<head>
<title>上传文件 , http://www.chinabs.net </title>
<script language=”C#” runat=”server”>
 //This method is called when the “upload” button id pressed
 public void UploadFile(object sender , EventArgs E)
 {
   //检查上传文件不为空
   if(myFile.PostedFile!=null)
   {     
  string nam = myFile.PostedFile.FileName ;
  //取得文件名(抱括路径)里最后一个”.”的索引
  int i= nam.LastIndexOf(“.”);
  //取得文件扩展名
  string newext =nam.Substring(i);
  //这里我自动根据日期和文件大小不同为文件命名,确保文件名不重复
  DateTime now = DateTime.Now; 
  string newname=now.DayOfYear.ToString()+myFile.PostedFile.ContentLength.ToString(); 
  //保存文件到你所要的目录,这里是IIS根目录下的upload目录.你可以改变.
  //注意: 我这里用Server.MapPath()取当前文件的绝对目录.在asp.net里”\”必须用”\\”代替
  myFile.PostedFile.SaveAs(Server.MapPath(“\\upload\\”+newname+newext)); 
  //得到这个文件的相关属性:文件名,文件类型,文件大小
  fname.Text=myFile.PostedFile.FileName;
  fenc.Text=myFile.PostedFile.ContentType ;
  fsize.Text=myFile.PostedFile.ContentLength.ToString();
   }
 }
</script>
</head>
<body>
<center>
<h3> 文件上传的实例, 来自<a href=”http://www.chinabs.net”>中国BS网</a></h3>
<form id=”uploderform” method=”post” action=”FileUpload.aspx” enctype=”multipart/form-data”  runat=”server” >
<table border=”1″ cellspacing=”2″ cellpadding=”2″ >
<tr> <td><h5>选择要上传的文件:</h5></td</tr>
<tr>
<td>
<input type=”file” id=”myFile” runat=”server” NAME=”myFile”>
</td>
</tr>
<tr><td>
<input type=”button”  value=”上 传” OnServerClick=”UploadFile” runat=”server” ID=”Button1″ NAME=”Button1″>
</td></tr>
</table>
</form>
<br>
<br>
<table border=”1″ cellspacing=”2″>
<tr><td><b>文件资料</b></td>
<td>&nbsp;</td> 
</tr>
<tr>
<td>文件名 :</td>
<td><asp:label id=”fname” text=”” runat=”server” /></td></tr>
<tr>
<td>文件类型 :</td>
<td><asp:label id=”fenc” runat=”server” /></td></tr>
<tr>
<td>文件大小 :(in bytes)</td>
<td><asp:label id=”fsize” runat=”server” /></td></tr>
</table>
<br>
<br>
<br>
</center>
</body>
</html>

服务器应用程序不可用

服务器应用程序不可用
您试图在此 Web 服务器上访问的 Web 应用程序当前不可用。请点击 Web 浏览器中的“刷新”按钮重试您的请求。

管理员注意事项: 详述此特定请求失败原因的错误信息可在 Web 服务器的系统事件日志中找到。请检查此日志项以查明导致该错误发生的原因。

——————————————————————————————————————————————

此问题因1.1与2.0版的.net程序共用一个应用程序池造成。将不同版本的应用程序从应用程序池独立出来即可。

访问 IIS 元数据库失败

访问 IIS 元数据库失败。
说明: 执行当前 Web 请求期间,出现未处理的异常。请检查堆栈跟踪信息,以了解有关该错误以及代码中导致错误的出处的详细信息。

异常详细信息: System.Web.Hosting.HostingEnvironmentException: 访问 IIS 元数据库失败。

用于运行 ASP.NET 的进程帐户必须具有对 IIS 元数据库(如
IIS://servername/W3SVC)的读访问权。有关如何修改元数据库权限的信息,请参见
http://support.microsoft.com/?kbid=267904

源错误:

执行当前 Web 请求期间生成了未处理的异常。可以使用下面的异常堆栈跟踪信息确定有关异常原因和发生位置的信息。 

堆栈跟踪:

[HostingEnvironmentException: 访问 IIS 元数据库失败。]
   System.Web.Configuration.MetabaseServerConfig.MapPathCaching(String
siteID, VirtualPath path) +690
  
System.Web.Configuration.MetabaseServerConfig.System.Web.Configuration.IConfigMapPath.MapPath(String siteID, VirtualPath vpath) +9
   System.Web.Hosting.HostingEnvironment.MapPathActual(VirtualPath
virtualPath, Boolean permitNull) +174
   System.Web.CachedPathData.GetConfigPathData(String configPath) +398
   System.Web.CachedPathData.GetConfigPathData(String configPath) +263
   System.Web.CachedPathData.GetVirtualPathData(VirtualPath virtualPath,
Boolean permitPathsOutsideApp) +166
   System.Web.Configuration.RuntimeConfig.GetLKGRuntimeConfig(VirtualPath
path) +187

——————————————————————————–
版本信息: Microsoft .NET Framework 版本:2.0.50727.42; ASP.NET 版本:2.0.50727.42

解决方案:

在运行中输入cmd,然后在MSDOS环境下输入:

cd   C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727,回车

然后输入aspnet_regiis /r ,回车,问题解决。

用VS2005开发ASP.NET 2.0数据库程序 (转载)

用VS2005开发ASP.NET 2.0数据库程序
发布: 九度IT
注册: 2005-12-10
高级工程师
 2005-12-25, 22:41

     一、 简介
  
    在2005年11月7日,微软正式发行了.net 2.0(包括ASP.NET 2.0),Visual Studio 2005和SQL Server 2005。所有这些部件均被设计为可并肩独立工作。也就是说,ASP.NET版本1.x和版本2.0可以安装在同一台机器上;你可以既有Visual Studio.NET 2002/2003和Visual Studio 2005,同时又有SQL Server 2000和SQL Server 2005。而且,微软还在发行Visual Studio 2005和SQL Server 2005的一个 Express式的SKU。注意,该Express版并不拥有专业版所有的特征。
  
    2.0除了支持1.x风格的数据存取外,自身也包括一些新的数据源控件-它们使得访问和修改数据库数据极为轻松。使用这些数据源控件时,你只需简单地添加该控件到ASP.NET页面并通过这些控件的属性来配置连接串和SQL查询即可。然后,通过把数据Web控件的DataSourceID属性设置为数据源控件的ID,该数据源控件就能被绑定到一个数据Web控件(如GridView)上。现今,必须靠编写代码来创建连接,创建命令,指定SQL查询,检索一个DataReader或DataSet,并且把它绑定到数据Web控件的日子已经过去了。这些步骤能够通过使用声明性数据源控件来代替。(当然,你还能通过使用你的1.x代码中的熟悉的步骤编程地存取数据。)
  
    在本文中我们将看一下怎样连接和显示来自一ASP.NET 2.0数据库的数据。具体地说,我们将讨论怎样使用编程和声明性方法来存取数据,以及分析通过GridView控件来显示数据的基本操作。
  
    二、 在Visual Studio 2005中操作数据库
  
    当你安装Visual Studio 2005的任何版本时,你总是被询问是否你也想安装SQL Server 2005 Express版本。如果你选择Yes,这将安装你的开发包中的SQL Server 2005 Express版本-注意,在此你正在安装Visual Studio 2005!(SQL Server 2005 Express版本可以与SQL Server的其它版本一起安装,包括SQL Server 2000和SQL Server 2005的其它版本。)
  
    如果你在当前工程中使用SQL Server 2000,那么你可以通过企业管理器来以最舒适的方式操作数据库。尽管你仍能使用企业管理器来操作SQL Server 2000,或使用SQL Server 2005的管理Studio来操作你的SQL Server 2005数据库;但是,你也能通过Visual Studio 2005的数据连接来管理这些数据库。我提及这些是因为对于SQL Server 2005 Express版本来说,不存在一个象SQL Server 2000的企业管理器或SQL Server 2005的管理 Studio这样的GUI工具;代之的是,你必须通过Visual Studio 2005来创建和管理你的SQL Server 2005 Express版本数据库。
  
    提示 管理SQL Server 2005 Express版本数据库
  
    如果你有任何其它除 Express以外的SQL Server 2005版本,你可以在你的机器上安装客户端工具,它包括管理Studio-管理SQL Server 2005数据库的GUI工具。如果你安装了这个工具,你还可以使用它来管理SQL Server 2005 Express版本数据库。
  
  
  
  为了通过Visual Studio 2005来管理一个数据库,请选择到Server Explorer;在其上,你将找到一个数据连接结点(见上图的快照)。你可以通过在数据连接结点上单击鼠标右键来添加新的数据库连接并且选择”Add Connection”。这将会调出一个对话框提示你一些信息,如数据库服务器、认证信息、使用什么数据库等。如果你在自己的机器上安装了SQL Server 2005 Express版本,那么即缺省地通过使用名为SQL Express的实例安装了这个数据库。因此,要连接到的服务名将是YourMachineName\SQL Express或.\SQL Express。除了连接到一个现有数据库外,你还可以通过在数据连接结点上单击鼠标右键并且选择创建新的SQL Server数据库来创建一个新的数据库。
  
    一旦一个数据库被添加到该数据连接选项卡上,你就可以通过适当的文件夹来添加、删除或修改数据表,存储过程,视图等。为了创建一新的数据表或存储过程,右击适当的文件夹并且选择”Add New X”菜单选项;为了修改一现有数据表、存储过程或视图,双击之即可。这将把它们调用到Visual Studio中-在此你可以据需要修改它。你也可以观察和修改在单个数据表中的数据-这是通过右击一个数据表名并且选择”显示数据表数据”来实现的。
  
    三、 添加一数据库到App_Data文件夹
  
    除了通过数据连接选择卡添加现有数据库外,你还可以添加一个站点特定的数据库到该网站的App_Data文件夹下。App_Data是一新的,保留在ASP.NET 2.0中的文件夹-它被设计来存储数据有关的内容,包括SQL数据库文件(.mdf文件)、Access数据库文件(.mdb文件)、XML文件等。从一个ASP.NET网站工程,你可以轻松地创建并且添加一新的SQL Server 2005 Express数据库到你的工程-通过右击Solution Explorer中的App_Data文件夹并且选择”Add New Item”。然后,从”Add New Item”对话框(显示如下)中,选择添加一新的SQL数据库。
  
  
  
  如果你想跟随本文的步骤,那么请在App_Data文件夹下创建一个称为Customers.mdf的SQL Server 2005 Express数据库。然后,添加一个数据表到这个称为Customers的数据库-用下面字段列:CustomerID(一个自动增加的主键字段),Name,City,State和ZipCode。然后,通过VS 2005添加一些记录到这个数据表。
  
    另外,你还能添加现有Access数据库文件甚至SQL Server 2000数据库文件。(注意:为了添加一现有SQL Server 2000 .mdf文件,你将需要确定它是第一次从企业管理器上分离;为此,在企业管理器上右击数据库名字,再选择”All Tasks”并且选择”Detach数据库”。一旦你分离开该数据库并且把它添加到ASP.NET 2.0工程,你就可以通过企业管理器重新依附它。)

     四、 把SqlDataSource控件连接到数据库
  
    现在,既然我们看到了怎么创建并且通过Visual Studio的接口来使用数据库;下面,让我们把注意力转到从一个ASP.net 2.0 Web页面访问和显示来自一数据库的数据上。ASP.NET 2.0包括了几个新的数据源控件-它们的唯一目的是提供到数据的声明性存取。共有五个内置的数据源控件-它们都能够在Visual Studio中的工具箱的”数据”部分找到(请见下边的屏幕快照)。
  
  
  
  ·SqlDataSource-用于检索和修改来自于一个关系数据库的数据。这里的”Sql”并不意味着这种数据源只与微软SQL Server一起工作;而是可以与其它任何一种关系数据库一起工作:SQL Server,Access,Oracle,等等。如果你在连接到一个SQL Server数据库,那么控件将会非常聪明地在内部启用SqlClient类。
  
    ·AccessDataSource-用于检索和修改来自于一个Access数据库文件的数据。你可能想知道,如果SqlDataSource能够与Access数据库文件一起工作,那么为什么还存在这个控件呢?其实,这个Access数据源控件使得你更容易地连接到一个Access数据库-你只要指定到Access数据库的.mdb文件的路径即可。注意在使用SqlDataSource时,你需要使用一完全限定的指定数据提供者的连接串。
  
    ·ObjectDataSource-用于通过一个商业对象来检索和修改数据。理想地,你的ASP.NET应用程序包括一组类-它形成中间层(而不是让ASP.NET页直接操作数据库)。如果你有如此的结构,那么可以使用ObjectDataSource来查询中间层。
  
    ·XMLDataSource-用于检索来自一XML文件的数据。
  
    ·SiteMapDataSource-用于提供只读存取定义在站点地图中的站点结构。这个控件在当你想要在一个TreeView或Menu控件中显示一个站点的结构时使用。
  
    在本文中,我们将只讨论Sql数据源控件,并且仅分析其基本功能。
  
    首先,让我们添加一个Sql数据源控件到你的ASP.NET页面。从设计视图中,Sql数据源控件包含一个”灵敏标签”-它列举出它的常用功能。该”Configure Data Source”灵敏标签链接将激活一个向导-它将一步步引导你通过整个的配置数据源的过程。这个向导主要有三个步骤(和一个可选的”子步骤”):
  
    1. 选择你的数据连接-在第一步中,我们需要指定连接到什么数据库。这个屏幕包含在App_Data文件夹中数据库的一个下拉列表和在数据连接选项卡中的一个下拉列表。还有一个”New Connection”按钮-你可以点击它,如果你想要连接到一个不在这些位置之一中的数据库。如果你继续下去,可以从下拉列表框中选择Customers.mdf选项。
  
    a) 子步骤:如果这是你添加连接的第一次,你将会被提示是否你想要把连接串保存到Web.config之中;而且如果这样的话,应该是连接串的名字。如果你继续下去,我选择用名字CustomersConnectionString把连接串保存到Web.config中。
  
    2. 设置Select语句-下一步是指定你想要返回什么记录,应用什么样的条件语句以及返回数据的排序顺序。为此,你可以通过使用向导来选择一个数据表或视图并且选择返回哪一列,或你可以手工地输入一个SELECT语句。无论哪一种方法,都是让Sql数据源控件返回来自Customers数据表的所有的列-换句话说,让它实现”SELECT * FROM Customers”。
  
    3. 查询测试-你可以针对数据库运行你的SELECT查询以得到返回数据的一个预览。请自由地点击”Test查询”按钮;你应该看见所有的来自该Customers数据表的所有记录。
  
    一旦你配置好SqlDataSource,请拿出一点时间看一下Source视图并且检查一下为Sql数据源控件所使用的声明性标记:
  
  <asp:SqlDataSource ID=”SqlDataSource1″ runat=”server”
  ConnectionString=”<%$ ConnectionStrings:CustomersConnectionString %>”
  SelectCommand=”SELECT * FROM [Customers]”>
  </asp:SqlDataSource>
  
    有几点要注意:首先,ConnectionString属性使用了新的句法<%$ … %>。这个句法从Web.config文件中检索ConnectionStrings节的值的CustomersConnectionString值。换句话说,它从Customers数据库中获取连接串-该串是我们在Sql数据源控件的向导的子步骤中保存下来的;其次,SELECT查询语句是在控件的SelectCommand属性中指定的。
  
    这些数据源控件其自身只与数据一起工作。他们不显示数据。如果你通过你的浏览器访问这个ASP.NET页面,你将发现没有产生输出。为了观察由我们刚才创建的Sql数据源控件所返回的数据,我们需要添加一个数据Web控件。对于本文来说,让我们使用GridView控件-你也可以在工具箱的”数据”节中找到它。该GridView是ASP.NET 1.x的DataGrid控件的”老大哥”-它提供了一些新的特性。在本文中,我们只分析到GridView的简单的数据绑定。
  
    现在,我们把一个GridView控件拖动到你的ASP.NET页面上。从设计视图中,该GridView的灵敏标签包括一个”Choose Data Source”选项并且有一个下拉列表的所有的数据源控件在该页面上。把这个下拉列表设置为SqlDataSource1-即是我们刚添加的Sql数据源控件的ID。一旦做完这些,该GridView将自动地有一个BoundFields添加到它上面-对于由数据源所返回的每一列(该GridView的BoundField等价于DataGrid中的BoundColumn)。通过GridView的灵敏标签来设置”Choose Data Source”下拉列表就可以把GridView的DataSourceID属性设置为所选择数据源控件的ID。
  
    就这么多,不需要写一句代码!下面是通过一浏览器观看该GridView时的一个屏幕快照。
  
  
  
  通过使用GridView和Sql数据源控件,我们就能够在30秒内从一个空白页转到一个显示数据库数据表的内容的页面。事实上,我们可以在另一个30秒内完成把分页、双向排序、删除和编辑支持添加到该GridView上,现在且不多谈!) 
   
     五、 编程连接到一数据库
  
    如我们前面所见,使用一个SqlDataSource检索信息非常快捷,但是如果你想要编程地存取数据又会怎样呢?或者,也许你已经有了现成的代码-该代码将取得你想要的精确数据并且据需要进行管理;并且一旦完成,即修改你将要在一个GridView中所显示的数据。没有问题,你可以就象在1.x中一样地在2.0中存取数据-通过创建一个到数据库的连接,创建一个命令,指定查询,填充一个DataReader或DataSet,然后使用该控件的DataSource属性和DataBind()方法把结果绑定到数据Web控件。
  
    下列代码显示出一个ASP.net页面的Page_Load事件处理器-它编程地把Customers数据库数据表的内容绑定到GridView控件gVCustomers上:
  
  Protected Sub Page_Load(ByVal sender As Object, _
  ByVal e As System.EventArgs) Handles Me.Load
   If Not Page.IsPostBack Then
    ’Start by determining the connection string value
    Dim connString As String = ConfigurationManager.ConnectionStrings(connStringName).ConnectionString
    ’创建一个SqlConnection实例
    Using myConnection As New SqlConnection(connString)
     ’指定SQL查询
     Const sql As String = “SELECT * FROM Customers”
     ’创建一个SqlCommand实例
     Dim myCommand As New SqlCommand(sql, myConnection)
     ’取回一个DataSet
     Dim myDataSet As New DataSet
     ’创建一个SqlDataAdapter查询
     Dim myAdapter As New SqlDataAdapter(myCommand)
     myAdapter.Fill(myDataSet)
     ’把DataSet绑定到GridView
     gvCustomers.DataSource = myDataSet
     gvCustomers.DataBind()
     ’关闭连接
     myConnection.Close()
    End Using
   End If
  End Sub
  
    在此,要注意几点:为了取得连接串,我们可以参考Web.config中的连接串设置-使用句法为
  ConfigurationManager.ConnectionStrings(connStringName).ConnectionString。其中,connStringName的值应该是在Sql数据源控件向导(CustomersConnectionString)的子步骤中指定的值。另外注意,Visual Basic 8(2.0中使用的VB版本)现在支持Using关键字-这是在前面的版本中仅适于C#的一个语言特点。
  
    编程地存取数据和输出结果等同于使用Sql数据源控件的情况。
  
    六、 结论
  
    在本文中,我们分析了在Visual Studio 2005中使用ASP.NET 2.0数据库的情形。我们讨论了怎样通过Visual Studio管理数据库,以及怎样通过App_Data文件夹来添加网站特定的数据库。最后,我们分析了怎样使用Sql数据源控件和编程的方式来存取数据。当使用一个数据源控件时,通过设置GridView的DataSourceID属性来把数据绑到一个GridView控件上;当编程地访问该数据时,通过把数据赋值给GridView的DataSource属性和调用GridView的DataBind()方法来实现把数据绑定到GridView。(后一种方法遵循在ASP.NET 1.x中使用的模式来绑定数据到一个DataGrid。)不管使用哪一种方式来访问数据,最终的结果,如在一用户浏览器中所见的,皆是相同的。

http://www.9doit.com/Artielc/1655/ShowPost.aspx