• 笔记0403


    1. Page的ResolveClientUrl与ResolveUrl读取路径

    一、Page对象的ResolveClientUrl与ResolveUrl

    Page.ResolveClientUrl():返回相对于当前页面的一个相对地址

    Page.ResolveUrl():返回相对于当前应用程序的一个相对地址

    但是两个方法的地址通过Server.MapPath()获取的绝对地址是一样的!

    例如:

    新建一个应用程序,根目录是“D:\MyApplication”,在根目录下新建如下目录、页面以及图片

    页面:TestFolder/TestPage.aspx

    图片:TestFolder/Images/TestImg.png

    在TestPage.aspx页面里分别调用

    String url1 = Page.ResolveClientUrl("Images/TestImg.png");             //结果:Images/TestImg.png
    String path1 = Server.MapPath(url1);                                                 //结果:D:\MyApplication\TestFolder\TestImg.png
    String url2 = Page.ResolveUrl("Images/TestImg.png");                      //结果:TestFolder/TestImg.png
    String path2 = Server.MapPath(url2);                                                 //结果:D:\MyApplication\TestFolder\TestImg.png

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

    ResolveClientUrl返回相对于当前页面下文件的地址
    ResolveUrl则返回页面所在应用程序下的相对地址


    例如:
    页面:~/Student/main.aspx
    图像:~/Images/copy.gif
    (这里~表示应用程序根目录)


    使用一:
    resolveClientUrl=Page.ResolveClientUrl("Images/copy.gif")
    resolveUrl=Page.ResolveUrl("Images/copy.gif")
    在页面main.aspx里使用copy.gif图像,则使用标题上的两种方法返回的结果如下
    ResolveClientUrl:Images/copy.gif
    ResolveUrl:/Student/Images/copy.gif

    使用二:
    resolveClientUrl=Page.ResolveClientUrl("~/Images/copy.gif")
    resolveUrl=Page.ResolveUrl("~/Images/copy.gif")
    在页面main.aspx里使用copy.gif图像,则使用标题上的两种方法返回的结果如下
    ResolveClientUrl:../Images/copy.gif
    ResolveUrl:/Images/copy.gif

    ResolveClientUrl用途之一:

    母版页面中,脚本或样式的路径采用Page.ResolveClientUrl进行获取,这样不同目录下使用了母版页的页面都能自动获取到对应脚本或样式文件的路径了。

    2. 如何:向 ASP.NET Web 服务器控件添加客户端脚本事件

    2.1 RegisteClientScriptInclude

    RegisterClientScriptInclude 方法的此重载接受 type 参数以进一步指定客户端脚本包含的标识。

    RegisterClientScriptInclude 在已呈现的页的顶部添加一个脚本块。

    <%@ Page Language="C#"%>
    <script runat="server">
      public void Page_Load(Object sender, EventArgs e)
      {
        // Define the name, type and url of the client script on the page.
        String csname = "ButtonClickScript";
        String csurl = "script_include.js";
        Type cstype = this.GetType();
            
        // Get a ClientScriptManager reference from the Page class.
        ClientScriptManager cs = Page.ClientScript;
    
        // Check to see if the include script exists already.
        if (!cs.IsClientScriptIncludeRegistered(cstype, csname))
        {
          cs.RegisterClientScriptInclude(cstype, csname, csurl);
        }
    
      }
    </script>
    <html>
      <head>
        <title>ClientScriptManager Example</title>
      </head>
      <body>
         <form id="Form1"
             runat="server">
            <input type="text" id="Message"> <input type="button" value="ClickMe" onclick="DoClick()">
         </form>
      </body>
    </html>

    此示例需要一个名为 Script_include.js 的 JavaScript 文件,它包含以下内容: 

    function DoClick() {Form1.Message.value='Text from include script.'}

    2.2  Page.ClientScript   获取用于管理脚本、注册脚本和向页添加脚本的 ClientScriptManager 对象。 

    使用 ClientScript 属性获取一个可用于管理脚本、注册脚本和向网页添加脚本的 ClientScriptManager 对象。

    2.3 ClientScriptManager类  

    在 Web 应用程序中定义用于管理客户端脚本的方法。 

    ClientScriptManager 类用于管理客户端脚本并将它们添加到 Web 应用程序中。可以从 Page 对象的 ClientScript 属性获取对 ClientScriptManager 类的引用。

    通过在网页的 HTML 标记中包含脚本,可以声明方式向网页添加客户端脚本。然而,有些情况下需要动态添加客户端脚本。若要动态添加脚本,根据您想添加脚本的时间及方式,使用 RegisterClientScriptBlock 方法、RegisterClientScriptInclude 方法、RegisterStartupScript 方法或 RegisterOnSubmitStatement 方法。

    向ASP.NET网页动态添加客户端脚本

    • 在服务器代码中,调用下表中列出的一种方法。

       
      方法说明

      RegisterClientScriptBlock

      向页的顶部添加一个脚本块。以字符串形式创建脚本,然后将其传递给方法,方法再将脚本添加到页中。可以使用此方法将任何脚本插入到页中。请注意,脚本可能在所有元素完成之前呈现到页中;因此,您可能无法从脚本中引用页上的所有元素。

      RegisterClientScriptInclude

      RegisterClientScriptBlock 方法类似,但此方法将添加引用外部 .js 文件的脚本块。包含文件在任何其他动态添加的脚本之前添加;因此,您可能无法引用页上的某些元素。

      RegisterStartupScript

      向页中添加一个脚本块,该脚本块在页完成加载后引发页的 onload 事件之前执行。该脚本通常不创建为事件处理程序或函数;它通常只包含要执行一次的语句。

      RegisterOnSubmitStatement

      添加响应页的 onsubmit 事件而执行的脚本。该脚本在提交页之前执行,允许您取消提交。

      下面的代码示例演示如何向页中添加在用户单击按钮(该按钮将页回发至服务器)时执行的客户端脚本。客户端脚本将显示弹出窗口,请求用户确认回发。

    3. 

    System.Collections名称空间的接口

    3.1  System.Collections名称空间的接口

    System.Collections名称空间定义了一些接口,很多集合类实现这些接口以提供对其内容的访问权限。表10-1列出了关键接口。

    表10-1  System.Collections的关键接口

        

        

    ICollection

    定义所有非泛型集合类型的一般特征

    (如大小、枚举、线程安全性)

    IComparer

    允许比较两个对象

    IDictionary

    允许一个非泛型集合对象使

    用名/值对表示其内容

    IDictionaryEnumerator

    枚举支持IDictionary的类型的内容

    IEnumerable

    返回给定集合的IEnumerator接口

    IEnumerator

    启用集合中For Each风格的迭代的条目

    IList

    提供在对象列表中添加、删除和

    索引条目的行为。此外,该接口定

    义一些成员来确定实现的集合类型

    是否为只读的和/或固定大小的容器


    很多接口是通过接口层次结构相关的,而其他接口是独立的类型。图10-1说明了各个类型之间的关系(我们说过,允许一个接口派生自多个接口)。

    3.2 . ICollection的作用

    ICollection接口是System.Collections名称空间中最基本的接口,其中定义了集合类型所支持的行为。简言之,这个接口提供了一个最小的成员集合,允许确定(a)容器中的条目数,(b)容器的线程安全性,以及(c)将内容复制到System.Array类型中的能力。ICollection的正式定义如下所示(注意,ICollection扩展了IEnumerable):

    Public Interface ICollection  
    Inherits IEnumerable  
    Sub CopyTo(ByVal array As Array, ByVal index As Integer)  
    ReadOnly Property Count() As Integer 
    ReadOnly Property IsSynchronized() As Boolean 
    ReadOnly Property SyncRoot() As Object 
    End Interface 

    3.3 . IDictionary的作用

    字典只是维护一组名称值对的集合。例如,可以构建一个实现IDictionary的自定义类型,以便存储可以按照ID或昵称(例如,名称)检索的Car对象(值)。由于有这种功能,因此可以看到IDictionary接口定义了Keys和Values属性以及Add()、Remove()和Contains()方法。通过类型索引器可以获得单个条目,本章稍后将会介绍类型索引器,它允许使用类似于数组的语法检索子条目。下面是正式定义:

    Public Interface IDictionary  
    Inherits ICollection, IEnumerable  
    Sub Add(ByVal key As Object, ByVal value As Object)  
    Sub Clear()  
    Function Contains(ByVal key As Object) As Boolean 
    Function GetEnumerator() As IDictionaryEnumerator  
    Sub Remove(ByVal key As Object)  
    ReadOnly Property IsFixedSize() As Boolean 
    ReadOnly Property IsReadOnly() As Boolean 
    Property Item(ByVal key As Object) As Object 
    ReadOnly Property Keys() As ICollection  
    ReadOnly Property Values() As ICollection  
    End Interface 

    3.4 . IDictionaryEnumerator的作用

    仔细观察一下,可以注意到IDictionary.GetEnumerator()返回IDictionaryEnumerator类型的实例。IDictionaryEnumerator只是一个强类型的枚举器,因为它通过添加如下功能扩展IEnumerator:

    Public Interface IDictionaryEnumerator  
    Inherits IEnumerator  
    ReadOnly Property Entry() As DictionaryEntry  
    ReadOnly Property Key() As Object 
    ReadOnly Property Value() As Object 
    End Interface 

    注意,IDictionaryEnumerator允许通过Entry属性遍历字典中的条目,它返回一个System.Collections.DictionaryEntry类类型。此外,也可以使用Key/Value属性遍历这个名/值对。

    4.5 . IList的作用

    System.Collections的最后一个关键接口是IList,它提供了向索引容器中插入、删除和向索引容器中添加或去掉索引条目的能力:

    Public Interface IList  
    Inherits ICollection, IEnumerable  
    Function Add(ByVal value As Object) As Integer 
    Sub Clear()  
    Function Contains(ByVal value As Object) As Boolean 
    Function IndexOf(ByVal value As Object) As Integer 
    Sub Insert(ByVal index As Integer, ByVal value As Object)  
    Sub Remove(ByVal value As Object)  
    Sub RemoveAt(ByVal index As Integer)  
    ReadOnly Property IsFixedSize() As Boolean 
    ReadOnly Property IsReadOnly() As Boolean 
    Property Item(ByVal index As Integer) As Object 
    End Interface 

     4. c# hashTable的遍历【2种方法】与排序【3种方法】

    private void Form1_Load(object sender, EventArgs e)  
    {  
        Hashtable ht = new Hashtable();  
      
        ht.Add("job", "a");  
        ht.Add("jobmon", "20");  
          
        //单个取值,方法比较特别  
        string a = ht["jobmon"].ToString();  
        //Console.WriteLine(a);  
      
        //第一种方法遍历  
        foreach(DictionaryEntry de in ht)  
        {  
            Console.WriteLine(de.Key);  
            Console.WriteLine(de.Value);  
        }  
      
        Console.WriteLine("-------------------------");  
          
        //第二种方法遍历  
        IDictionaryEnumerator enumerator = ht.GetEnumerator();  
        while (enumerator.MoveNext())  
        {  
            Console.WriteLine(enumerator.Key);  
            Console.WriteLine(enumerator.Value);  
        }  
      
        Console.WriteLine("++++++++++++++++++++++++++");  
        //hashtable的排序第一种方法,按照键的大小排序  
      
        ArrayList al = new ArrayList(ht.Keys);  
      
        al.Sort();  
        al.Reverse(); //反向排序  
      
        foreach (string str in al)  
        {  
            Console.WriteLine(str + "  " + ht[str]);  
        }  
      
        Console.WriteLine("++++++++++++++++++++++++++");  
        //hashtable的排序第二种方法,按照值的大小排序  
      
        ArrayList alv = new ArrayList(ht.Values);  
        alv.Sort();  
          
        foreach (string str in alv)  
        {  
            IDictionaryEnumerator enumerator2 = sl.GetEnumerator();  
      
            while (enumerator2.MoveNext())  
            {  
                if (str.Equals(enumerator2.Value.ToString()))  
                {  
      
                    Console.WriteLine(enumerator2.Key + ":" + enumerator2.Value);          
                }  
                  
            }  
      
              
        }  
      
        Console.WriteLine("++++++++++++++++++++++++++");  
        //hashtable的排序第三种方法,用SortedList代替hashtable  
      
        SortedList sl = new SortedList();  
      
        sl.Add("a", "a1");  
        sl.Add("c", "c1");  
        sl.Add("b", "b1");  
      
        IDictionaryEnumerator enumerator1 = sl.GetEnumerator();  
        while (enumerator1.MoveNext())  
        {  
            Console.WriteLine(enumerator1.Key);  
            Console.WriteLine(enumerator1.Value);  
        }  
      
    }  

    5. 

    Web 是没有状态的,ASP.NET 页面也没有状态,它们在到服务器的每个往返过程中被实例化、执行、呈现和处理。作为 Web 开发人员,您可以使用众所周知的技术(如以会话状态将状态存储在服务器上,或将页面回传到自身)来添加状态

    ViewState是一种机制,ASP.NET 使用这种机制来跟踪服务器控件状态值,否则这些值将不作为 HTTP 窗体的一部分而回传。也就是说在页面刷新或者回传的时候控件的值将被清空,我们在aspx.cs中也经常用ViewState来存储值,作为一种存储状态,取代会话状态(session),举个例子

    1、一般的服务器控件

    <asp:Label ID="Label1" runat="server" Text="这是Label1的值"></asp:Label>

    <asp:Button ID="Button1" runat="server" Text="Button" />

    如果点击Button1,则触发按钮事件

    protected void Button1_Click(object sender, EventArgs e)

        {

            Label1.Text = "改变Label1的值";

        }

    很显然Label1的值会显示为“改变Label1的值”,对ViewState有了解的人应该知道,这是因为ASP.NET用这种机制把Label1保存至__VIEWSTATE这个隐藏域中,然后回传时直接从此隐藏域中取值,赋值给Label1,减轻服务器负担,在页面查看源文件可以看到这个,这个是base64编码的字符串,并不是加密,更复杂的说且是在方法Page.SavePageStateToPersistenceMedium输出前保存、并由Page.LoadPageStateFromPersistenceMedium加载,对于这两个方法大家可以去研究

      <input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwUJNjkxODQwNzM1ZGREm/D7KtJXowDFHnrxVg6pUDM3rQ==" />

    如果是纯HTML控件,每次回传必然会回到控件的初始值

    但是我们可以禁用ViewState机制,只要在控件或者page或者在web.config上配置,比如

    <asp:Label ID="Label1" runat="server" Text="这是Label1" EnableViewState="False"></asp:Label>

    则点击上面按钮时,Label1的值会显示为“这是Label1”,而并不是改变Label1的值,这是因为ViewState 负责穿越回传期保持它的值。但又因为 ViewState 是 禁止 的, 所以 Label 丢失了ViewState为其保存的值,于是变回到初始值

     

    2、特殊的服务器控件

    我们再举一个例子

    <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>//服务器控件

    <input type="text" id="TextBox2"  runat="server"  />//HTML控件,但是加了服务器标识

    <input type="text" id="TextBox3"  />//HTML控件

    <asp:Button ID="Button1" runat="server" Text="Button" />

     

    点击按钮,

     

    发现第一个服务器控件,第二个加了服务器标识的HTML控件,页面回传时值没有变化,而第三个纯HTML控件值被清空,即回到初始值,这种情况使我们早就料到的,于是我们继续尝试着,对服务器控件试用EnableViewState="False",再来看结果

     

    点击按钮,

     

    这个结果真是让我们失望,很明显我已经禁用ViewState,理应该是三个控件值都为空,即都回到初始值,考察资料得到

    ViewState 是不负责存储诸如 TextBox等这些继承自 IPostBackDataHandler 接口的控件的值的更改的。

    简单的说继承自 IPostBackDataHandler 接口的控件的值由控件自身控制保存,而与EnableViewState=false没有关系,前台页面__VIEWSTATE的值是控件自身控制写入_VIEWSTATE的,怎么写入的要看IPostBackDataHandler 接口的实现方式【先反序列化ViewState,然后 LoadPostData 事件被触发,然后把反序列化后的值写入控件,具体见http://msdn.microsoft.com/zh-cn/library/system.web.ui.ipostbackdatahandler.aspx,说实话我也不知道我理解的对不对。求大神指教】

    大概如下图

    在微软的帮助文档中得知(http://support.microsoft.com/?id=316813)

    也就是说通常情况下类似TextBox发送到服务器的属性由 IPostBackDataHandler 界面来处理,不管VIEWSTATE有没有禁止,它都会在回传时往里面填值,当然这个值是来自HTTP 提交头里

    3、我们经常试用的Viewstate

    我经常在aspx.cs中试用Viewstate来存储数据状态,比如

    Viewstate[“name”]=”殷海超”;,然后程序会把这个Viewstate保存为键-值对形式,这是会有一个序列化和反序列化的过程(序列化就是将对象的状态信息转换为可以存储或传输形式的过程。其实就是将对象持久化,比如说把对象保存为二进制或者是XML的方式。可以将对象序列到流、磁盘、内存和网络等等。相反,反序列化则是将存储或传输形式转换为对象的过程。),Viewstate[“name”]=”殷海超”这是序列化,因为其实这里是序列化为字符串放置至HTML页面中(中间过程何其复杂。还未理解);string name= Viewstate[“name”];这是反序列化

     

    4ViewState为控件赋值的步骤

     

    protected void Page_Init(object sender, EventArgs e)

    {

            TextBox1.Text = "bb";

    }

    protected void Page_Load(object sender, EventArgs e)

    {

            TextBox1.Text = "aa";

    }

    未操作之前,我们往第一个控件中输入cc

     

    我们点击按钮后:显示下图

     

    先执行Page_Init()事件,TextBox1.Text先会是bb,然后执行称为 LoadViewState 的事件,在这里 Page 类从隐藏的域 __VIEWSTATE 中为诸如 ViewState 属性为 enabled 的 Label 控件装载值。然后 LoadPostBackData 事件被触发,在这里 Page 类从 HTTP 提交头(POST headers)中装载继承自 IPostBackDataHandler 接口的控件的值,即这时TextBox1.Text是cc,然后会执行Page_Load,这时TextBox1.Text是aa。

  • 相关阅读:
    简单说说数据库表设计的三种范式
    存储过程简单的动态订单号
    Asp.Net页面生命周期
    jq 小笔记,上传判断其格式
    吃一垫长一智
    离散事件模拟
    二叉树查找树
    冷暖自知
    基督徒的人生箴言
    迷宫寻路
  • 原文地址:https://www.cnblogs.com/jonson1126/p/2997764.html
Copyright © 2020-2023  润新知