1. 程式人生 > 其它 >ASP.NET AJAX(9)__Profile Service什麼是ASP.NET Profile如何使用ASP.NET ProfileProfile ServiceProfile Service預

ASP.NET AJAX(9)__Profile Service什麼是ASP.NET Profile如何使用ASP.NET ProfileProfile ServiceProfile Service預

什麼是ASP.NET Profile

  • 可以為每個使用者(包括匿名使用者)儲存資訊
  • 通過在Web.config中的配置即可在應用程式中使用
  • 強型別的屬性
  • 可以定義屬性組
  • 可以通過自定義ProfileProvider來擴充

如何使用ASP.NET Profile

  1. 配置ProfileProvider(可以使用內建的SqlProfileProvider)
  2. 配置Profile的屬性
一個使用ASP.NET Profile的示例

首先,執行開啟Visual studio 2008命令提示工具(開始——程式——Visual studio 2008——Visual studio Tool)輸入指令:aspnet_regsql -A p -sqlexportonly profileset.sql 回車

這樣我們就可以在F:Microsoft Visual StudioMicrosoft Visual Studio 2008VC下得到一個名為profileset.sql的檔案,命令中的“p”就程式碼ASP.NET 為profile提供的一個數據庫的支援

然後我們開啟資料庫管理器,我電腦裡裝的Microsoft SQL Server的develop版本,VS2008帶的是Express版本,但是在某些功能上限制,比如它限制資料庫最大為4G,雖然這在通常情況下已經是夠用的了,但是難免我們會遇到一寫很大的資料庫,比我上回我就遇到一個寶潔公司的一個專案,他的資料庫有10G,這種情況下Express版本就有問題了

在資料庫管理工具裡執行我們剛才得到的SQL檔案,我們最好使用資料庫的最高許可權管理員登陸,以免遇到一些許可權上的問題

然後我們會在資料庫裡發現一個名為aspnetdb的資料庫,這個資料庫是預設生成的,名字可以是在我們開始使用命令列的時候指定的,

開啟這個資料庫,我們可以看到四個表(除系統表以外)aspnet_Applications、aspnet_Profile、aspnet_SchemaVersions、aspnet_Users,這些資料表,按照他的名字,我們就可以猜到它的用途啦

然後開啟VS中的web.config,在<configuration>節點下新增connectionStrings節點

<connectionStrings>
        <add name="ProfileDatabase" connectionString="Data Source=XIAOYAOJIAN;Initial Catalog=aspnetdb;Persist Security Info=True;User ID=sa;Password=*******"/>
    </connectionStrings>

這個就不多做解釋了,學過asp.net的人,估計沒一個不明白這個的意思吧

然後,在system.web節點下,新增如下內容

<profile enabled="true" defaultProvider="SqlProvider">
            <providers>
                <clear/>
        <!--type表示我們使用的ProfileProvider的型別,connectionStringName指定我們上面配置的connectionString,applicationName表示應用程式的名字,將會體現的資料庫中-->
                <add name="SqlProvider" type="System.Web.Profile.SqlProfileProvider" connectionStringName="ProfileDatabase" applicationName="ProfileSample" description="Sample for ASP.NET profile and Profile Service"/>
            </providers>
      <!--配置屬性-->
            <properties>
        <!--定義屬性,並指定型別-->
                <add name="Name" type="System.String"/>
                <add name="Email" type="System.String"/>
                <add name="Age" type="System.Int32"/>
        <!--定義一個屬性組-->
                <group name="Address">
                    <add name="City" type="System.String"/>
                    <add name="Street" type="System.String"/>
                    <add name="PostalCode" type="System.String"/>
                </group>
            </properties>
        </profile>

這裡需要注意一點,在每個屬性中都有一個allowAnonymous屬性,指定是否可為匿名使用者使用,預設是false,如果設定為true,則它也可以為一些匿名使用者儲存一些資訊

接下來我們就可以建立也一個頁面使用它

前臺程式碼

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="ProfileUsage.aspx.cs" Inherits="Demo08_ProfileUsage" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
        <asp:TextBox ID="txtUsername" runat="server"></asp:TextBox>
        <asp:Button ID="btnLogInOut" runat="server" Height="24px" Text="btnLogIn/Out" Width="113px"
            OnClick="btnLogInOut_Click" />
        <hr />
        Name:<asp:TextBox ID="txtName" runat="server"></asp:TextBox><br />
        Age:<asp:TextBox ID="txtAge" runat="server"></asp:TextBox><br />
        Email:<asp:TextBox ID="txtEmail" runat="server"></asp:TextBox><br />
        City:<asp:TextBox ID="txtCity" runat="server"></asp:TextBox><br />
        Street:<asp:TextBox ID="txtStreet" runat="server"></asp:TextBox><br />
        Postal Code:<asp:TextBox ID="txtPostalCode" runat="server"></asp:TextBox><br />
        <asp:Label ID="lblMessage" runat="server" Text=""></asp:Label><br />
        <asp:Button ID="btnShowProfile" runat="server" Text="Show" OnClick="btnShowProfile_Click" />
        <asp:Button ID="btnSave" runat="server" Text="Save" OnClick="btnSave_Click" />
    </form>
</body>
</html>

後臺程式碼:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.Security;

public partial class Demo08_ProfileUsage : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {

    }
    protected void btnLogInOut_Click(object sender, EventArgs e)
    {
        if (this.User.Identity.IsAuthenticated)
        {
            this.lblMessage.Text = this.User.Identity.Name + " logout!";
            FormsAuthentication.SignOut();//登出使用者
        }
        else
        {
            this.lblMessage.Text = this.txtUsername.Text + " login!";
            FormsAuthentication.SetAuthCookie(this.txtUsername.Text, false);//使使用者登陸
        }
    }
    protected void btnShowProfile_Click(object sender, EventArgs e)
    {
        if (this.Profile.Age == 0)//沒有profile,這是個不完整的做法,我們只做一個示例用
        {
            this.txtName.Text = "";
            this.txtEmail.Text = "";
            this.txtCity.Text = "";
            this.txtAge.Text = "";
            this.txtPostalCode.Text = "";
            this.txtStreet.Text = "";

            this.lblMessage.Text = this.User.Identity.Name + " No profile!";
        }
        else
        {
            this.txtName.Text = this.Profile.Name;
            this.txtEmail.Text = this.Profile.Email;
            this.txtCity.Text = this.Profile.Address.City;
            this.txtAge.Text = this.Profile.Age.ToString();
            //使用屬性組中的內容
            this.txtPostalCode.Text = this.Profile.Address.PostalCode;
            this.txtStreet.Text = this.Profile.Address.Street;

            this.lblMessage.Text = this.User.Identity.Name + " profile loaded!";
        }
    }
    protected void btnSave_Click(object sender, EventArgs e)
    {
        this.Profile.Name = this.txtName.Text;
        this.Profile.Age = Int32.Parse(this.txtAge.Text);
        this.Profile.Email = this.txtEmail.Text;
        this.Profile.Address.City = this.txtCity.Text;
        this.Profile.Address.Street = this.txtStreet.Text;
        this.Profile.Address.PostalCode = this.txtPostalCode.Text;

        this.lblMessage.Text = this.User.Identity.Name + "  profile saved!";
    }
}

驗證頁面,首先在第一個文字框中屬於一個使用者名稱(隨意的),點選登陸,輸入個人資訊,點選SAVE,就可以儲存關於這個使用者的資訊,點選Logout,然後點選SHOW,顯示NO PROFILE,然後再登陸剛才那個使用者,點選SHOW,則顯示個人資訊

開啟資料庫aspnetdb中的aspnet_Applications表,可以看到類似如下內容

在這裡我們可以找到我們配置的ApplicationName

然後開啟aspnet_Users表,會看到型別如下內容

這裡能找到上一個表的ApplicationId,UserName,IsAnonymous等一系列資訊這就是我們通過profile設定進來的

儲存資訊的表,則是存放在了aspnet_Profile這個表裡,開啟我們可以找到幾中儲存的方式,可以模糊的看到我們儲存的資訊,因為它已經通過一種它的規則把它進行了序列化,我們不需要也沒必要去讀懂它

Profile Service

  • ASP.NET AJAX 1.0提供的Application Service中的一個
  • 另一個是Membership Service
  • .NET Framework 3.5中包含其他的Application Service

使用Profile Service

  • 出於安全性考慮,ASP.NET AJAX的Profile Service在預設情況下是不可用的
  • <profile Service enabled=”true|false" readAccessProperties="prop1,prop2,…" writeAccessProperties="prop1,prop2,…"  />

載入Profile Service

Sys.Services.ProfileService.load(propertyNames,//需要載入的Profile名,null表示全部

loadCompletedCallback,//載入成功的回撥函式

failedCallback,//載入失敗的回撥函式

userContext//可以隨意設定的上下文物件

);

function loadCompletedCallback(

number,//本次載入的Profile數量

userContext,//使用者隨意指定的上下文物件

methodName//即Sys.Services.ProfileService.load

){…}

function failedCallback(

error,//錯誤物件

userContext,//使用者隨意指定的上下文物件

methodName//即Sys.Services.ProfileService.load

){…}

獲取和修改Profile Service

var properties=Sys.Services.ProfileService.properties;

alert(properties.Name);

alert(properties.Address.City);

……

properties.Address={City:"tianjin",Street:"yashen road",PostalCode:"300350"};

properties.Save(…);

儲存Profile Service

Sys.Services.ProfileService.save(

propertyNames,//需要儲存的Profile名,null表示全部

saveCompletedCallback,//儲存成功的回撥函式

failedCallback,//載入失敗的回撥函式

userContext//這個,還用寫嗎?

);

function saveCompletedCallback(

number,//本次載入的Profile數量

userContext,

methodName//即Sys.Services.ProfileService.save

){…}

function failedCallback(

error,//錯誤物件

userContext,

methodName//即Sys.Services.ProfileService.save

){…}

一個使用Proile Service的示例

建立一個名為ProfileService.aspx的頁面

前臺程式碼

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="ProfileService.aspx.cs" Inherits="Demo08_ProfileService" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
    <script language="javascript" type="text/javascript">
        function loadProfiles() {
            Sys.Services.ProfileService.load(null, loadCompleted);
        }

        function loadCompleted() {
            var properties = Sys.Services.ProfileService.properties;
            if (properties.Age) {//如果有Profile
                $get("txtName").value = properties.Name;
                $get("txtAge").value = properties.Age;
                $get("txtCity").value = properties.Address.City;
                $get("txtPostalCode").value = properties.Address.PostalCode;
                $get("message").innerHTML = "Profile loaded!";
            }
            else {
                $get("txtName").value = "";
                $get("txtAge").value = "";
                $get("txtCity").value = "";
                $get("txtPostalCode").value = "";
                $get("message").innerHTML = " No Profile";
            }
        }

        function saveProfiles() {
            var properties = Sys.Services.ProfileService.properties;
            properties.Name = $get("txtName").value;
            properties.Age = parseInt($get("txtAge").value, 10);
            properties.Address.City = $get("txtCity").value;
            properties.Address.PostalCode = $get("txtPostalCode").value;

            Sys.Services.ProfileService.save(null,saveCompleted);
        }
        function saveCompleted() {
            $get("message").innerHTML = "profile saved";
        }
    </script>
</head>
<body>
    <form id="form1" runat="server">
        <asp:ScriptManager ID="ScriptManager1" runat="server">
            
        </asp:ScriptManager>
        
        <asp:TextBox ID="txtUserName" runat="server"></asp:TextBox>
        <asp:Button ID="btnLogIn" runat="server" Text="Login" OnClick="btnLogin_Click" />
        <asp:Button ID="btnLogout" runat="server" Text="Logout" OnClick="btnLogout_Click" />
        <hr />
        
        Name: <input type="text" id="txtName" /><br />
        Age: <input type="text" id="txtAge" /><br />
        Email: <input type="text" id="txtEmail" /><br />
        City: <input type="text" id="txtCity" /><br />
        Street: <input type="text" id="txtStreet" /><br />
        Postal Code: <input type="text" id="txtPostalCode" /><br />
        
        <div id="message" style="color:Red;"></div><br />
        
        <input type="button" value="Show" onclick="loadProfiles()" />
        <input type="button" value="Save" onclick="saveProfiles()" />
    </form>
</body>
</html>

後臺程式碼

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.Security;

public partial class Demo08_ProfileService : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        
    }
    protected void btnLogin_Click(object sender, EventArgs e)
    {
        FormsAuthentication.SetAuthCookie(this.txtUserName.Text, false);
    }
    protected void btnLogout_Click(object sender, EventArgs e)
    {
        FormsAuthentication.SignOut();
    }
}

然後我們開啟web.config進行配置,找到<system.web.extensions>下的<scripting>下的<webServices>,增加以下內容

<!--這裡不可以直接寫一個屬性組,而要把屬性組裡的屬性一一列舉出來-->
        <profileService enabled="true" readAccessProperties="Name,Age,Email,Address.City,Address.Street,Address.PostalCode" writeAccessProperties="Name,Age,Email,Address.City,Address.Street,Address.PostalCode"/>

這樣,使用方式和之前的一樣,但是我們就使用AJAX的方式使用了Profke Service

其他的一些Profile Service屬性

  • timeout屬性:設定超時時間(Sys.Services.ProfileService.get_timeout()/set_timtout();)
  • defaultLoadCompletedCallback屬性
  • defaultSaveCompletedCallback屬性
  • defaultFailedCallback屬性

Profile Service預載入

AJAX技術是很容易被濫用的,因為我們在對網頁進行操作的時候,隨便的一滑鼠劃過效果,可能就會產生一個Round-trip,如果設計上有濫用,則會很大程式上增加了服務端的壓力,而且如果設計的不好,有時候不旦沒有提高使用者體驗,反而是降低了,還有呢,就是一個安全性的問題,這個以後會寫到,所以就要在合適的時候使用預載入,來減少這種Round-trip

Profile Service預載入的方式就是在ScriptManager中做的一些操作

如果我們要使用這個功能,很簡單,只需要在<ScriptManager>中新增類似如下程式碼

<ProfileService LoadProperties="Name, Email, Address.City, Address.Street" />

Profile Service實現方式

Profile Service的功能

  • 使用AJAX方式獲取Profile
  • 使用AJAX方式儲存Profile

如果沒有這個Profile Service,我們要做這些事情,則需要在客戶端呼叫一個Web Service,事實上Profile Service它的內部實現就是這樣的,他是對客戶端執行伺服器端方法給出的一種特殊實現,在呼叫定義的ASP.NET AJAX程式集上的ProfileService類,最終工作的為以下的三個方法

  • GetAllPropertiesForCurrentUser
  • GetPropertiesForCurrentUser
  • SetPropertiesForCurrentUser

晚二十點二十七