Пошаговое руководство. Использование служб приложений ASP.NET
Обновлен: Ноябрь 2007
ASP.NET предоставляет службы приложения в сети Интернет, с помощью которых можно разрешить клиентским приложениям доступ к сведениям о проверке подлинности пользователей, ролях и профиле. Доступ к данной информации могут получать клиентские приложения, написанные на других языках, работающие в других операционных системах. Единственное требование заключается в том, что данные клиенты должны поддерживать взаимодействие по протоколу SOAP 1.1.
Данное пошаговое руководство состоит из нескольких частей:
В части 1 показаны способы настройки веб-узла ASP.NET для представления служб приложения.
В части 2 демонстрируются способы построения консольного приложения Windows, которое имеет доступ к сведениям о проверке подлинности пользователей, ролях и профиле. В данном пошаговом руководстве демонстрируется процесс построения консольного приложения Windows, при этом службы приложения ASP.NET доступны для любых клиентских приложений, которые могут отправлять и получать сообщения в формате SOAP.
Обязательные компоненты
Для выполнения этого пошагового руководства потребуются следующие компоненты:
Visual Studio 2008. Для данного пошагового руководства нельзя использовать Microsoft Visual Web Developer 2005, поскольку будет создано консольное приложение Windows, которое не поддерживается в Visual Web Developer, экспресс-выпуск.
Установленный на компьютере Microsoft SQL Server или экспресс-выпуск SQL Server.
Предоставление служб приложений
В данном разделе описаны способы предоставления служб приложения как части веб-узла ASP.NET, чтобы любой клиент в сети могу иметь к ним доступ. Этапы, описанные в данном пошаговом руководстве, применимы только для сервера.
Примечание. |
---|
Для выполнения данного пошагового руководства необходимо использовать веб-узел с файловой системой. При выполнении данного пошагового руководства предполагается, что для запуска примеров используется сервер разработки ASP.NET вместо служб IIS. Дополнительные сведения см. в разделе Веб-серверы в Visual Web Developer. |
Создание веб-узла служб приложения
Откройте Visual Studio 2008.
В меню Файл выберите команду Создать веб-узел.
Откроется диалоговое окно Создать веб-узел.
В группе Установленные шаблоны Visual Studio выберите Веб-узел ASP.NET.
В списке Расположение выберите пункт Файловая система.
В текстовом поле Папка введите имя веб-узла WcfApplicationServices.
Примечание. Можно использовать любое имя. Если используется другое имя, следует запомнить это имя, чтобы далее в этом пошаговом руководстве подставлять именно его.
Нажмите кнопку ОК.
Visual Studio создаст новый веб-узел ASP.NET и откроет страницу Default.aspx.
В обозревателе решений щелкните имя веб-узла и нажмите клавишу F4, чтобы открыть окно Свойства.
В окне Свойства присвойте свойству Использовать динамические порты значение False.
Таким образом, Visual Studio получает команду указывать фиксированный порт вместо произвольного порта при запуске сервера разработки ASP.NET. Для выполнения данного пошагового руководства необходимо знать фиксированный номер порта, который будет использован при создании клиентских прокси-классов и файлов конфигурации. Дополнительные сведения см. в разделе Пошаговое руководство. Указание порта сервера ASP.NET Development Server.
Примечание. Из окна Страницы свойств нет доступа к окну Свойства веб-узла.
В поле Номер порта введите 8080.
Примечание. Можно использовать любой доступный порт. Если используется другой порт, следует отметить номер порта, чтобы впоследствии можно было заменить его на номер 8080.
Сведения о членстве ASP.NET, ролях и профиле хранятся в базе данных. Эта база данных создается автоматически при необходимости. В следующей процедуре описаны способы создания пользователей и ролей для приложения, в результате чего будет автоматически создана база данных.
Создание сведений о пользователях и ролях
Добавьте к веб-узлу файл Global.asax и замените в этом файле существующий метод Application_Start на следующий код:
<%@ Application Language="VB" %> <script runat="server"> Sub Application_Start(ByVal sender As Object, ByVal e As EventArgs) ' Code that runs on application startup ' Warning. This code is just for test purposes ' to generate a SQL Express database quickly. ' In a production environment, you must set ' a SQL standard database separately. If Not Roles.RoleExists("Administrators") Then Roles.CreateRole("Administrators") End If If Not Roles.RoleExists("Friends") Then Roles.CreateRole("Friends") End If End Sub </script>
<%@ Application Language="C#" %> <script runat="server"> void Application_Start(object sender, EventArgs e) { // Code that runs on application startup // Warning. This code is just for test purposes // to generate a SQL Express database quickly. // In a production environment, you must set 3-25 // a SQL standard database separately. if (!Roles.RoleExists("Administrators")){ Roles.CreateRole("Administrators"); } if (!Roles.RoleExists("Friends")){ Roles.CreateRole("Friends"); } } </script>
При первом запуске веб-приложения код создает локальную базу данных Aspnetdb.mdf и добавит в нее роли Administrators и Friends. Эта база данных используется для хранения сведений об учетных данных, ролях и профиле пользователя.
Откройте страницу Default.aspx и добавьте в нее следующую разметку. В результате будут добавлены ссылки на страницу входа, страницу сведений о профиле и страницу нового пользователя. Эти страницы будут добавлены позднее в данном пошаговом руководстве.
<%@ Page Language="VB" AutoEventWireup="true" CodeFile="Default.aspx.vb" Inherits="_Default" %> <!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 id="Head1" runat="server"> <title>Application Services Home Page</title> </head> <body> <form id="form1" runat="server"> <div> <h2>Enter Users' Information</h2> The following selections enable you to create users, and assign them roles and profile information. <p> <asp:Label ID="LoggedId" Font-Bold="true" ForeColor="red" runat="server"/> </p> <table border="1"> <tr> <td align="left">Login to change profile</td> <td align="left"><asp:LoginStatus ID="LoginStatus1" runat="server" /></td> </tr> <tr> <td align="left">Define profile information (you must login first)</td> <td align="left"><a href="Profile.aspx" target="_self">Profile Information</a></td> </tr> <tr> <td align="left">Create user and assign role</td> <td align="left"><a href="CreateUser.aspx"target="_self">New User</a></td> </tr> </table> </div> </form> </body> </html>
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %> <!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>Application Services Home Page</title> </head> <body> <form id="form1" runat="server"> <div> <h2>Enter Users' Information</h2> The following selections enable you to create users, and assign them roles and profile information. <p> <asp:Label ID="LoggedId" Font-Bold="true" ForeColor="red" runat="server"/> </p> <table border="1"> <tr> <td align="left">Login to change profile</td> <td align="left"><asp:LoginStatus ID="LoginStatus1" runat="server" /></td> </tr> <tr> <td align="left">Define profile information (you must login first)</td> <td align="left"><a href="Profile.aspx" target="_self">Profile Information</a></td> </tr> <tr> <td align="left">Create user and assign role</td> <td align="left"><a href="CreateUser.aspx"target="_self">New User</a></td> </tr> </table> </div> </form> </body> </html>
В файле с выделенным кодом Default.aspx добавьте в метод Page_Load код, который будет проверять, прошел ли пользователь проверку подлинности.
Следующий пример показывает, как проверить, прошел ли пользователь проверку подлинности.
Imports System Imports System.Data Imports System.Configuration Imports System.Collections Imports System.Web Imports System.Web.Security Imports System.Web.UI Imports System.Web.UI.WebControls Imports System.Web.UI.WebControls.WebParts Imports System.Web.UI.HtmlControls Partial Public Class _Default Inherits System.Web.UI.Page Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs) If HttpContext.Current.User.Identity.IsAuthenticated Then LoggedId.Text = HttpContext.Current.User.Identity.Name + " you are logged in" End If End Sub End Class
using System; using System.Data; using System.Configuration; using System.Collections; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Web.UI.HtmlControls; public partial class _Default : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { if (HttpContext.Current.User.Identity.IsAuthenticated) { LoggedId.Text = HttpContext.Current.User.Identity.Name + " you are logged in"; } } }
Добавьте страницу с именем Login.aspx. Убедитесь, что установлен флажок Размещать код в отдельном файле.
Добавьте элемент управления Login в файл Login.aspx.
В следующем примере показана разметка для файла Login.aspx.
<%@ Page Language="VB" AutoEventWireup="true" %> <!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>Login Page</title> </head> <body> <form id="form1" runat="server"> <div> <asp:Login ID="Login1" runat="server" /> </div> </form> </body> </html>
<%@ Page Language="C#" AutoEventWireup="true" %> <!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>Login Page</title> </head> <body> <form id="form1" runat="server"> <div> <asp:Login ID="Login1" runat="server"/> </div> </form> </body> </html>
Добавьте страницу с именем Profile.aspx и убедитесь, что установлен флажок Размещать код в отдельном файле.
Добавьте на страницу Profile.aspx следующую разметку:
<%@ Page Language="VB" AutoEventWireup="true" CodeFile="Profile.aspx.vb" Inherits="_Profile" %> <!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 id="Head1" runat="server"> <title>Profile Page</title> </head> <body> <form id="form1" runat="server"> <div> <h3>Current Authenticated User Profile Information</h3> <a href="Default.aspx">back to default page</a> <h4>Read Profile Information</h4> <table> <tr> <td align="left">User Name</td> <td align="left"> <asp:Label ID="Label1" runat="server" Text="Label"/> </td> </tr> <tr> <td align="left">User Roles</td> <td align="left"> <asp:Label ID="Label2" runat="server" Text="Label"/> </td> </tr> <tr> <td align="left">First Name</td> <td> <asp:Label ID="Label3" runat="server" Text="Label"/> </td> </tr> <tr> <td align="left">Last Name</td> <td> <asp:Label ID="Label4" runat="server" Text="Label"/> </td> </tr> <tr> <td align="left">ID#</td> <td> <asp:Label ID="Label5" runat="server" Text="Label"/> </td> </tr> </table> <asp:Button ID="Button2" runat="server" onclick="Button2_Click" Text="Read Profile Information" /> <hr /> <h3>Update Profile Information </h3> <table> <tr> <td align="left">First Name</td> <td align="left"><asp:TextBox ID="TextBox1" runat="server"/></td> </tr> <tr> <td align="left">Last Name</td> <td align="left"><asp:TextBox ID="TextBox2" runat="server"/></td> </tr> <tr> <td align="left">ID#</td> <td align="left"><asp:TextBox ID="TextBox3" runat="server"/></td> </tr> </table> <asp:Button ID="Button1" runat="server" onclick="Button1_Click" Text="Update Profile Data" /> </div> </form> </body> </html>
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Profile.aspx.cs" Inherits="ProfileInformation" %> <!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 id="Head1" runat="server"> <title>Profile Page</title> </head> <body> <form id="form1" runat="server"> <div> <h3>Current Authenticated User Profile Information</h3> <a href="Default.aspx">back to default page</a> <h4>Read Profile Information</h4> <table> <tr> <td align="left">User Name</td> <td align="left"> <asp:Label ID="Label1" runat="server" Text="Label"/> </td> </tr> <tr> <td align="left">User Roles</td> <td align="left"> <asp:Label ID="Label2" runat="server" Text="Label"/> </td> </tr> <tr> <td align="left">First Name</td> <td> <asp:Label ID="Label3" runat="server" Text="Label"/> </td> </tr> <tr> <td align="left">Last Name</td> <td> <asp:Label ID="Label4" runat="server" Text="Label"/> </td> </tr> <tr> <td align="left">ID#</td> <td> <asp:Label ID="Label5" runat="server" Text="Label"/> </td> </tr> </table> <asp:Button ID="Button2" runat="server" onclick="Button2_Click" Text="Read Profile Information" /> <hr /> <h3>Update Profile Information </h3> <table> <tr> <td align="left">First Name</td> <td align="left"><asp:TextBox ID="TextBox1" runat="server"/></td> </tr> <tr> <td align="left">Last Name</td> <td align="left"><asp:TextBox ID="TextBox2" runat="server"/></td> </tr> <tr> <td align="left">ID#</td> <td align="left"><asp:TextBox ID="TextBox3" runat="server"/></td> </tr> </table> <asp:Button ID="Button1" runat="server" onclick="Button1_Click" Text="Update Profile Data" /> </div> </form> </body> </html>
Страница профиля содержит элементы управления Label, используемые для отображения имени и роли пользователя, и элементы управления TextBox, используемые для изменения имен и идентификаторов пользователей.
В файле с выделенным кодом для страницы Profile.aspx добавьте следующий код:
Imports System Imports System.Data Imports System.Configuration Imports System.Collections Imports System.Web Imports System.Web.Security Imports System.Web.UI Imports System.Web.UI.WebControls Imports System.Web.UI.WebControls.WebParts Imports System.Web.UI.HtmlControls Partial Public Class _Profile Inherits System.Web.UI.Page Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs) Dim Profile As ProfileCommon = TryCast(HttpContext.Current.Profile, ProfileCommon) If HttpContext.Current.User.Identity.IsAuthenticated Then Label1.Text = HttpContext.Current.User.Identity.Name Dim roles As String() = _ System.Web.Security.Roles.GetRolesForUser() Label2.Text = "" For Each r As String In roles Label2.Text += r + " " Next Label3.Text = Profile.FirstName() Label4.Text = Profile.LastName Label5.Text = Profile.EmployeeId Else Label1.Text = "User is not Authenticated" Label1.ForeColor = System.Drawing.Color.Red End If End Sub Protected Sub Button2_Click(ByVal sender As Object, ByVal e As EventArgs) If HttpContext.Current.User.Identity.IsAuthenticated Then Label1.Text = HttpContext.Current.User.Identity.Name Dim roles As String() = _ System.Web.Security.Roles.GetRolesForUser() Label2.Text = "" For Each r As String In roles Label2.Text += r + " " Next Label3.Text = Profile.FirstName Label4.Text = Profile.LastName Label5.Text = Profile.EmployeeId Else Label1.Text = "User is not Authenticated" Label1.ForeColor = System.Drawing.Color.Red End If End Sub Protected Sub Button1_Click(ByVal sender As Object, ByVal e As EventArgs) If HttpContext.Current.User.Identity.IsAuthenticated Then Profile.FirstName = TextBox1.Text Profile.LastName = TextBox2.Text Profile.EmployeeId = TextBox3.Text End If End Sub End Class
using System; using System.Data; using System.Configuration; using System.Collections; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Web.UI.HtmlControls; public partial class ProfileInformation : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { ProfileCommon Profile = HttpContext.Current.Profile as ProfileCommon; if (HttpContext.Current.User.Identity.IsAuthenticated) { Label1.Text = HttpContext.Current.User.Identity.Name; string[] roles = Roles.GetRolesForUser(); Label2.Text = ""; foreach (string r in roles) { Label2.Text += r + " "; } Label3.Text = Profile.FirstName; Label4.Text = Profile.LastName; Label5.Text = Profile.EmployeeId; } else { Label1.Text = "User is not Authenticated"; Label1.ForeColor = System.Drawing.Color.Red; } } protected void Button2_Click(object sender, EventArgs e) { if (HttpContext.Current.User.Identity.IsAuthenticated) { Label1.Text = HttpContext.Current.User.Identity.Name; string[] roles = Roles.GetRolesForUser(); Label2.Text = ""; foreach (string r in roles) { Label2.Text += r + " "; } Label3.Text = Profile.FirstName; Label4.Text = Profile.LastName; Label5.Text = Profile.EmployeeId; } else { Label1.Text = "User is not Authenticated"; Label1.ForeColor = System.Drawing.Color.Red; } } protected void Button1_Click(object sender, EventArgs e) { if (HttpContext.Current.User.Identity.IsAuthenticated) { Profile.FirstName = TextBox1.Text; Profile.LastName = TextBox2.Text; Profile.EmployeeId = TextBox3.Text; } } }
Примечание. В предыдущем примере имя класса в файле с выделенным кодом было изменено на _Profile, чтобы избежать конфликта с экземпляром Profile.
Код на данной странице позволяет получать и изменять сведения о профиле пользователя.
Примечание. Проект не будет скомпилирован до тех пор, пока не будут включены свойства профиля для данного веб-узла. Это будет сделано в следующей процедуре.
Добавьте страницу с именем "CreateUser.aspx" и добавьте в нее следующую разметку.
<%@ Page Language="VB" AutoEventWireup="true" CodeFile="CreateUser.aspx.vb" Inherits="CreateUser" %> <!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>Add New User</title> </head> <body> <form id="form1" runat="server"> <div> <h2>Add New User</h2> <a href="Default.aspx">back to default page</a> <asp:CreateUserWizard ID="CreateUserWizard1" runat="server" OnCreatedUser="On_CreatedUser"> <wizardsteps> <asp:CreateUserWizardStep ID="CreateUserWizardStep1" runat="server" /> <asp:CompleteWizardStep ID="CompleteWizardStep1" runat="server" /> </wizardsteps> </asp:CreateUserWizard> <p> Check the following box to assign the user to the administrator role. Otherwise, the user will be assigned to the friends role by default. </p> <span style="font-weight:bold; color:Red">Administrator</span> <asp:CheckBox ID="CheckBox1" runat="server" /> </div> </form> </body> </html>
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="CreateUser.aspx.cs" Inherits="CreateUser" %> <!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 id="Head1" runat="server"> <title>Add New User</title> </head> <body> <form id="form1" runat="server"> <div> <h2>Add New User</h2> <a href="Default.aspx">back to default page</a> <asp:CreateUserWizard ID="CreateUserWizard1" runat="server" OnCreatedUser="On_CreatedUser"> <wizardsteps> <asp:CreateUserWizardStep ID="CreateUserWizardStep1" runat="server" /> <asp:CompleteWizardStep ID="CompleteWizardStep1" runat="server" /> </wizardsteps> </asp:CreateUserWizard> <p> Check the following box to assign the user to the administrator role. Otherwise, the user will be assigned to the friends role by default. </p> <span style="font-weight:bold; color:Red">Administrator</span> <asp:CheckBox ID="CheckBox1" runat="server" /> </div> </form> </body> </html>
В файле с выделенным кодом для страницы CreateUser.aspx добавьте следующий код:
Imports System Imports System.Data Imports System.Configuration Imports System.Collections Imports System.Web Imports System.Web.Security Imports System.Web.UI Imports System.Web.UI.WebControls Imports System.Web.UI.WebControls.WebParts Imports System.Web.UI.HtmlControls Partial Public Class CreateUser Inherits System.Web.UI.Page Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs) End Sub Protected Sub On_CreatedUser(ByVal sender As Object, ByVal e As EventArgs) Dim userName As String = CreateUserWizard1.UserName If CheckBox1.Checked Then HttpContext.Current.Response.Write(userName) Roles.AddUserToRole(userName, "Administrators") Else Roles.AddUserToRole(userName, "Friends") End If CheckBox1.Visible = False HttpContext.Current.Response.Redirect("~/default.aspx") End Sub End Class
using System; using System.Data; using System.Configuration; using System.Collections; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Web.UI.HtmlControls; public partial class CreateUser : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { } protected void On_CreatedUser(object sender, EventArgs e) { string userName = CreateUserWizard1.UserName; if (CheckBox1.Checked) { HttpContext.Current.Response.Write(userName); Roles.AddUserToRole(userName, "Administrators"); } else Roles.AddUserToRole(userName, "Friends"); CheckBox1.Visible = false; HttpContext.Current.Response.Redirect("~/default.aspx"); } }
На данной странице можно создавать пользователей и назначать для них роли.
На следующем этапе предлагается включить на веб-узле свойства проверки подлинности форм, ролей и профиля. Это можно сделать с помощью параметров в файле "Web.config".
Настройка свойств проверки подлинности, ролей и профиля
Откройте файл Web.config веб-узла.
В группе system.web измените установленную по умолчанию проверку подлинности Windows на Forms, как показано в следующем примере.
<authentication mode="Forms" />
В группе system.web настройте службу ролей, добавив элемент roleManager, как показано в следующем примере.
<roleManager enabled="true"/>
В группе system.web настройте службу профиля с помощью раздела profile и его элемента properties, как показано в следующем примере.
<profile enabled="true"> <properties> <add name="FirstName" type="String"/> <add name="LastName" type="String"/> <add name="EmployeeId" type="String"/> </properties> </profile>
Этот параметр профиля задает три свойства, которые будут управляться службой профиля ASP.NET. Во время выполнения ASP.NET будет динамически создавать класс типа ProfileCommon, содержащий эти свойства.
В следующем примере демонстрируется часть файла Web.config со всеми требуемыми изменениями.
<system.web> <!-- Other settings. --> <authentication mode="Forms" /> <roleManager enabled="true"/> <profile enabled="true"> <properties> <add name="FirstName" type="String"/> <add name="LastName" type="String"/> <add name="EmployeeId" type="String"/> </properties> </profile> </system.web>
Теперь можно приступать к созданию сведений о пользователе, которые впоследствии будут использованы для входа.
Создание пользователей и назначение сведений о профиле
Выберите в обозревателе решений страницу Default.aspx, а затем нажмите сочетание клавиш CTRL+F5, чтобы запустить эту страницу.
Страница откроется в обозревателе со следующим URL-адресом:
https://localhost:8080/WcfApplicationServices/Default.aspx
Выберите пункт Новый пользователь.
Отобразится страница "CreateUser.aspx".
Необходимо создать несколько пользователей и назначить для них предварительно определенные роли. Для этого следует ввести учетные данные пользователя и выбрать команду Создать пользователя.
Запишите созданные имена пользователей и пароли. Эти сведения потребуются для того, чтобы назначить или изменить сведения о профиле пользователя.
Например, создайте пользователя с именем “joeA” и установите флажок Администратор, чтобы пользователь joeA стал членом роли Administrators. Создайте второго пользователя с именем “joeNA” и не устанавливайте флажок Администратор. Пользователь joeNA будет членом роли Friends, но не будет членом роли Administrators. Роли Friends и Administrators были созданы кодом, который был добавлен ранее в метод Application_Start файла Global.asax.
После завершения создания пользователя произойдет переадресация на страницу Default.aspx.
На странице "Default.aspx" выберите команду Вход.
Отобразится страница "Login.aspx".
Следует выполнить вход с помощью учетных данных одного из ранее созданных пользователей.
Если вход выполнен успешно, произойдет переадресация на страницу Default.aspx.
Выберите пункт Сведения о профиле.
Отобразится страница "Profile.aspx".
Необходимо ввести или обновить сведения о профиле пользователя, для которого выполнен вход, путем введения имени, фамилии и номера идентификатора.
Выберите команду Обновить данные профиля.
Выберите пункт Чтение сведений о профиле.
Отобразится только что введенная информация. Этот шаг позволяет убедиться, что свойства профиля работают.
Создание пользователей и сведений о профиле завершено. Теперь следует открыть доступ к сведениям для клиентских приложений.
Сопоставление и настройка служб приложения
Теперь можно предоставить сведения о созданном пользователе с помощью служб приложения ASP.NET. Прежде чем получить доступ к учетным данным пользователя и сведениям о профиле клиента, необходимо создать файлы сопоставления (SVC), которые указывают на службы приложения. Таким образом можно открыть доступ к службам для любого приложения, запущенного на любой платформе, которое может принимать и получать сообщения в формате SOAP. Также необходимо настроить веб-узел таким образом, чтобы службы приложения предоставлялись в сети.
Создание файлов сопоставления служб приложения
Добавьте файл служб WCF (SVC-файл) на веб-узел и присвойте ему имя MyAuthenSvcWrap.svc.
Замените существующую директиву @ ServiceHost следующей директивой, которая ссылается на класс System.Web.ApplicationServices.AuthenticationService:
<%@ ServiceHost Language="VB" Service="System.Web.ApplicationServices.AuthenticationService" Factory="System.Web.ApplicationServices.ApplicationServicesHostFactory" Debug="true" %>
<%@ ServiceHost Language="C#" Service="System.Web.ApplicationServices.AuthenticationService" Factory="System.Web.ApplicationServices.ApplicationServicesHostFactory" Debug="true" %>
В данном примере службы не реализуется пользовательская служба проверки подлинности. Вместо этого вызывается встроенный класс System.Web.ApplicationServices.AuthenticationService.
Удалите файлы интерфейса и класса в каталоге App_Code (App_Code\MyAuthenSvcWrap и App_Code\IMyAuthenSvcWrap).
Эти файлы интерфейса и класса были созданы при добавлении SVC-файла в проект. Эти файлы не нужны, поскольку используется служба System.Web.ApplicationServices.AuthenticationService, и пользовательская служба не реализуется.
Добавьте еще один файл служб WCF (SVC-файл) на веб-узел и присвойте ему имя MyRoleSvcWrap.svc.
Откройте файл MyRoleSvcWrap.svc и замените его содержимое следующей директивой @ ServiceHost, создающей ссылку на класс System.Web.ApplicationServices.RoleService:
<%@ ServiceHost Language="VB" Service="System.Web.ApplicationServices.RoleService" Factory="System.Web.ApplicationServices.ApplicationServicesHostFactory" %>
<%@ ServiceHost Language="C#" Service="System.Web.ApplicationServices.RoleService" Factory="System.Web.ApplicationServices.ApplicationServicesHostFactory" %>
В каталоге App_Code удалите файлы интерфейса и класса для службы MyRoleSvcWrap.
Добавьте еще один файл служб WCF (SVC-файл) на веб-узел и присвойте ему имя MyProfileSvcWrap.svc.
Откройте файл MyProfileSvcWrap.svc и замените его содержимое следующей директивой, создающей ссылку на класс System.Web.ApplicationServices.ProfileService:
<%@ ServiceHost Language="VB" Service="System.Web.ApplicationServices.ProfileService" Factory ="System.Web.ApplicationServices.ApplicationServicesHostFactory" %>
<%@ ServiceHost Language="C#" Service="System.Web.ApplicationServices.ProfileService" Factory ="System.Web.ApplicationServices.ApplicationServicesHostFactory" %>
В каталоге App_Code удалите файлы интерфейса и класса для службы MyProfileSvcWrap.
Сохраните и закройте все SVC-файлы.
Теперь можно приступить к настройке веб-приложения для предоставления служб приложения.
Настройка служб приложения
Откройте файл Web.config или переключитесь на него.
Под разделом configSections добавьте новый раздел system.web.extensions.
В элементе scripting включите службы приложения с помощью раздела webServices.
В следующем примере показан готовый элемент system.web.extensions.
</configSections> <system.web.extensions> <scripting> <webServices> <authenticationService enabled="true" requireSSL = "false"/> <profileService enabled="true" readAccessProperties="FirstName,LastName,EmployeeId"/> <roleService enabled="true"/> </webServices> </scripting> </system.web.extensions> <appSettings/>
Добавьте в раздел system.serviceModel элемент serviceHostingEnvironment в качестве дочернего и установите его свойство aspNetCompatibilityEnabled в значение true.
В следующем примере показан готовый элемент serviceHostingEnvironment.
</runtime> <system.serviceModel> <serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>
В группе system.serviceModel настройте службы приложения, чтобы открыть к ним доступ для клиентских приложений с помощью протокола SOAP. Для этого выполните следующие действия:
В элементе system.serviceModel найдите элемент <behaviors><serviceBehaviors><behavior>, чей атрибут имени имеет значение “MyAuthenSvcWrapBehavior”.
Измените значение атрибута name элемента behavior с “MyAuthenSvcWrapBehavior” на “AppServiceBehaviors”. В этом пошаговом руководстве приложение настраивается на использование поведения AppServiceBehaviors для всех трех служб.
Удалите элементы behavior с именами “MyRoleSvcWrapBehavior” и “MyProfileSvcWrapBehavior” из элемента <system.serviceModel><behaviors><serviceBehaviors>.
В следующем примере показан готовый раздел <system.serviceModel> .
</runtime> <system.serviceModel> <serviceHostingEnvironment aspNetCompatibilityEnabled="true"/> <behaviors> <serviceBehaviors> <behavior name="AppServiceBehaviors"> <serviceMetadata httpGetEnabled="true" /> <serviceDebug includeExceptionDetailInFaults="true" /> </behavior> </serviceBehaviors> </behaviors>
В элементе <system.serviceModel><services><service> с именем “MyAuthenSvcWrapBehavior” измените значение атрибута behaviorConfiguration элемента behavior с “MyAuthenSvcWrapBehavior” на “AppServiceBehaviors”.
Измените значение атрибута name с “MyAuthenSvcWrap” на “System.Web.ApplicationServices.AuthenticationService”.
Настройте элемент <service><endpoint>, выполнив следующие действия:
Удалите атрибут address.
Измените значение атрибута binding с “wsHttpBinding” на “basicHttpBinding”.
Измените значение атрибута contract с “IMyAuthenSvcWrap” на “System.Web.ApplicationServices.AuthenticationService”.
Добавьте атрибут bindingNamespace и присвойте ему значение “https://asp.net/ApplicationServices/v200".
Удалите дочерний элемент identity.
В следующем примере показана разметка для элемента проверки подлинности service.
<service behaviorConfiguration="AppServiceBehaviors" name="System.Web.ApplicationServices.AuthenticationService"> <endpoint binding="basicHttpBinding" contract="System.Web.ApplicationServices.AuthenticationService" bindingNamespace="https://asp.net/ApplicationServices/v200" > </endpoint> </service>
Дополнительные сведения см. в разделе <service> Element.
Повторите шаг 8 для элемента MyAuthenSvcWrap.
В следующем примере показан завершенный элемент system.serviceModel.
<system.serviceModel> <serviceHostingEnvironment aspNetCompatibilityEnabled="true"/> <behaviors> <serviceBehaviors> <behavior name="AppServiceBehaviors"> <serviceMetadata httpGetEnabled="true" /> <serviceDebug includeExceptionDetailInFaults="true" /> </behavior> </serviceBehaviors> </behaviors> <services> <service behaviorConfiguration="AppServiceBehaviors" name="System.Web.ApplicationServices.AuthenticationService"> <endpoint binding="basicHttpBinding" contract="System.Web.ApplicationServices.AuthenticationService" bindingNamespace="https://asp.net/ApplicationServices/v200" /> </service> <service behaviorConfiguration="AppServiceBehaviors" name="System.Web.ApplicationServices.RoleService"> <endpoint binding="basicHttpBinding" contract="System.Web.ApplicationServices.RoleService" bindingNamespace="https://asp.net/ApplicationServices/v200" /> </service> <service behaviorConfiguration="AppServiceBehaviors" name="System.Web.ApplicationServices.ProfileService"> <endpoint binding="basicHttpBinding" contract="System.Web.ApplicationServices.ProfileService" bindingNamespace="https://asp.net/ApplicationServices/v200" /> </service> </services> </system.serviceModel> </configuration>
Теперь можно запустить веб-узел для активации служб приложения, которые будут использоваться клиентским приложением Windows. Это также позволяет выполнять проверку правильности работы инфраструктуры служб приложения.
Активация веб-узла для предоставления служб приложения
В обозревателе решений щелкните правой кнопкой мыши файл MyAuthenSvcWrap.svc и выберите пункт Просмотр в обозревателе.
Будет вызвана веб-служба, и в обозревателе появится страница, на которой приведены инструкции по тестированию службы. Запишите URL-адрес службы, поскольку он в дальнейшем понадобится на следующих этапах для доступа к службе из клиентского приложения.
Примечание. Не закрывайте обозреватель. При использовании сервера разработки ASP.NET обозреватель должен быть открытым, чтобы службы приложения оставались активными.
Настройка служб приложения в сети Интернет завершена, и службы приложения теперь доступны в сети Интернет. На следующем этапе будет выполнен вызов данных служб из клиентского приложения.
Использование служб приложения
В данном разделе демонстрируются способы создания клиентского приложения в виде консольного приложения Windows для доступа к службам приложения. Эти службы приложений могут вызываться любым клиентом, который может отправлять и получать сообщения в формате SOAP.
Для создания клиентского консольного приложения необходимо выполнить несколько стандартных действий:
Создать клиентское приложение.
Создать прокси-файлы служб приложения и связанные файлы конфигурации.
Добавить созданные прокси-файлы и файлы конфигурации в клиентское приложение и выполнить компиляцию приложения.
Вызвать операции службы приложения с помощью созданных прокси-файлов.
Примечание. При передаче в службу конфиденциальных данных пользователя, например учетных данных проверки подлинности, следует использовать SSL с протоколом HTTPS. Например, как показано в примере далее, можно изменить значение атрибута requireSSL элемента authenticationService с “false" на “true". Дополнительные сведения см. в разделах Безопасность транспортировки и Безопасность HTTP и веб-службы ASP.NET на веб-узле MSDN и в разделе Настройка протокола SSL в службах IIS 7.0 на веб-узле IIS.
Создание консольного приложения Windows
В Visual Studio в меню Файл выберите команду Добавить, после чего выберите пункт Новый проект.
Выберите желаемый язык, а затем в меню Установленные шаблоны Visual Studio выберите пункт Консольное приложение.
Присвойте приложению имя AppSvcClient, введите путь для приложения и нажмите кнопку ОК.
Visual Studio добавит проект в существующее решение и откроет файл класса по умолчанию.
Правой кнопкой мыши щелкните имя консольного приложения и нажмите кнопку Добавить ссылку.
В диалоговом окне Добавление ссылки щелкните вкладку .NET, выберите пункт System.ServiceModel и System.Runtime.Serialization, а затем нажмите кнопку ОК.
Таким образом будут добавлены пространства имен в проект, включающий классы, необходимые для использования прокси-классов.
Создание прокси-классов и сведений конфигурации для служб приложения
Теперь можно приступить к созданию прокси-классов и сведений конфигурации, которые позволят открыть доступ для консольного приложения к службам приложения из консольного приложения AppSvcClient. Для каждой службы приложения отдельно создается прокси-класс и конфигурация.
Создание прокси-классов для служб приложения
В меню Windows "Пуск" последовательно выберите пункты Все программы, Microsoft Visual Studio 2008, Средства Visual Studio и Командная строка Visual Studio 2008.
Примечание. При работе в Microsoft Vista следует выполнять эту команду от имени администратора.
В результате будет открыто окно командной строки Windows с параметрами среды, включающими путь к средствам платформы .NET Framework.
В командной строке Windows перейдите в каталог, в котором содержится файл Program.cs или Module1.vb для приложения AppSvcClient.
Создайте прокси-класс службы проверки подлинности с помощью служебной программы службы (Svcutil.exe). В командной строке Windows, открытой на шаге 1, введите следующую команду:
svcutil https://localhost:8080/WcfApplicationServices/MyAuthenSvcWrap.svc?wsdl /language:"VB"
svcutil https://localhost:8080/WcfApplicationServices/MyAuthenSvcWrap.svc?wsdl /language:"C#"
Примечание. По умолчанию установлен выходной язык C#. Флаг /language:"VB" требуется только для Visual Basic.
Значение "localhost:8080" должно совпадать с URL-адресом, используемым в данном пошаговом руководстве при запуске веб-узла. Если для сервера разработки ASP.NET используется другой номер порта, или назначается динамический порт, следует заменить соответствующее значение. При изменении номера порта следует обновить CONFIG-файл, созданный с помощью инструмента "Svcutil.exe", в целях соответствия новому номеру порта.
Имя SVC-файла в команде должно соответствовать имени, ранее использованному в данном пошаговом руководстве при создании SVC-файлов. Имя присваивается SVC-файлу прокси-класса в произвольном порядке; в данном примере имя прокси-класса совпадает с именем соответствующего SVC-файла.
Измените имя файла конфигурации output.config, созданного служебной программой службы, на App.config.
В обозревателе решений щелкните правой кнопкой мыши консольное приложение, выберите команду Добавить, выберите пункт Существующий элемент, выделите созданный файл прокси-класса AuthenticationService и нажмите кнопку Добавить.
В основном файле класса консольного приложения добавьте следующий код для создания теста.
Imports System.ServiceModel Module Module1 Sub Main(ByVal args As String()) If (args.Length <> 2) Then Console.WriteLine("missing args username password") Return End If Dim username As String = args(0) Dim password As String = args(1) Dim result As Boolean = False Dim customCredential As String = "Not Used by the default membership provider" Dim isPersistent As Boolean = True ' authentication ticket remains valid across sessions. 'BasicHttpBinding and endpoint are provided in app.config file. Dim authService As New AuthenticationServiceClient() result = authService.Login(username, password, customCredential, isPersistent) If result Then Console.WriteLine("Welcome " + username + ". You have logged in.") Else Console.WriteLine("We could not validate your credentials.") End If Console.WriteLine("Enter any key to exit.") Console.Read() End Sub End Module
using System; using System.Text; using System.ServiceModel; class Program { static void Main(string[] args) { if (args.Length < 1) { Console.WriteLine("missing args username password"); return; } string username = args[0]; string password = args[1]; bool result = false; // BasicHttpBinding and endpoint are provided in app.config file AuthenticationServiceClient authService = new AuthenticationServiceClient(); string customCredential = "Not Used by the default membership provider"; bool isPersistent = true; // authentication ticket remains valid across sessions. result = authService.Login(username, password, customCredential, isPersistent); if (result == true) Console.WriteLine("Welcome " + username + ". You have logged in."); else Console.WriteLine("Unable to login"); } }
Этот код позволяет передавать в службу имя пользователя и его пароль при запуске ее из консольного приложения. Можно использовать значения имен пользователей и паролей, созданных ранее в ходе выполнения данного пошагового руководства.
Это тестовое приложение получает сведения о привязке и конечных точках из файла App.config.
Протестируйте проект, выполнив следующие действия:
В Visual Studio выполните построение решения.
В командной строке перейдите в папку “\bin\debug" и запустите файл AppSvcClient.exe. Передайте в командной строке имя пользователя и пароль.
Консольное приложение отобразит сообщение, указывающее, что был выполнен вход.
Создайте прокси-класс службы профиля, скопировав следующую команду в командное окно Windows:
svcutil.exe https://localhost:8080/WcfApplicationServices/MyProfileSvcWrap.svc?wsdl /language:"VB" /config:app.config /mergeConfig
svcutil.exe https://localhost:8080/WcfApplicationServices/MyProfileSvcWrap.svc?wsdl /language:"C#" /config:app.config /mergeConfig
Параметр /config:app.config задает файл App.config в качестве файла конфигурации вместо файла output.config, заданного по умолчанию. Параметр /mergeConfig указывает, что данные конфигурации, созданные на этом шаге, должны быть объединены со сведениями, уже имеющимися в файле App.config в результате выполнения предыдущих шагов.
Создайте прокси-класс службы проверки подлинности, скопировав следующую команду в командное окно Windows:
svcutil.exe https://localhost:8080/WcfApplicationServices/MyAuthenSvcWrap.svc?wsdl /language:"VB" /config:app.config /mergeConfig
svcutil.exe https://localhost:8080/WcfApplicationServices/MyAuthenSvcWrap.svc?wsdl /language:"C#" /config:app.config /mergeConfig
Создайте прокси-класс службы роли, скопировав следующую команду в командное окно Windows:
svcutil.exe https://localhost:8080/WcfApplicationServices/MyRoleSvcWrap.svc?wsdl /language:"VB" /config:app.config /mergeConfig
svcutil.exe https://localhost:8080/WcfApplicationServices/MyRoleSvcWrap.svc?wsdl /language:"C#" /config:app.config /mergeConfig
В обозревателе решений щелкните правой кнопкой мыши консольное приложение, выберите команду Добавить, выберите пункт Существующий элемент, выделите три созданных файла прокси-класса и нажмите кнопку Добавить.
Прокси-классы находятся в той же папке, что и файл App.config, и имеют имена AuthenticationService, ProfileService и RoleService.
Замените код в классе Program следующим кодом:
Imports System Imports System.Collections.Generic Imports System.Text Imports System.ServiceModel Imports System.ServiceModel.Activation Imports System.ServiceModel.Channels Imports System.ComponentModel Imports System.Web Imports System.Net Module Module1 Class MyServiceTst Dim _host As String Public Property Host() As String Get Return _host End Get Set(ByVal value As String) _host = value End Set End Property Function GetCookies(ByVal oc As OperationContext) As CookieContainer Dim httpResponseProperty As HttpResponseMessageProperty = DirectCast(oc.IncomingMessageProperties(HttpResponseMessageProperty.Name), HttpResponseMessageProperty) If (httpResponseProperty.Equals(Nothing) = False) Then Dim cookieContainer As New CookieContainer() Dim header As String = httpResponseProperty.Headers(HttpResponseHeader.SetCookie) If header <> Nothing Then cookieContainer.SetCookies(New Uri("http://someuri.tld"), header) End If Return cookieContainer End If Return Nothing End Function Sub SetCookies(ByVal oc As OperationContext, ByVal cookieContainer As CookieContainer) Dim httpRequestProperty = New HttpRequestMessageProperty() httpRequestProperty = Nothing If oc.OutgoingMessageProperties.ContainsKey(HttpRequestMessageProperty.Name) Then httpRequestProperty = TryCast(oc.OutgoingMessageProperties(HttpRequestMessageProperty.Name), HttpRequestMessageProperty) End If If httpRequestProperty Is Nothing Then httpRequestProperty = New HttpRequestMessageProperty() oc.OutgoingMessageProperties.Add(HttpRequestMessageProperty.Name, httpRequestProperty) End If httpRequestProperty.Headers.Add(HttpRequestHeader.Cookie, cookieContainer.GetCookieHeader(New Uri("http://someuri.tld"))) End Sub Sub GetUserRoles(ByVal cookieContainer As CookieContainer) Dim roleSvc As New RoleServiceClient() Using New OperationContextScope(DirectCast(roleSvc.InnerChannel, IContextChannel)) SetCookies(OperationContext.Current, cookieContainer) Dim roles As String() = roleSvc.GetRolesForCurrentUser() If roles.Length = 0 Then Console.WriteLine("User does not belong to any role.") Else Dim userRoles As String = "" Dim i As Integer = 0 While i < roles.Length userRoles += roles(i) + " " Global.System.Math.Max(Global.System.Threading.Interlocked.Increment(i), i - 1) End While Console.WriteLine("User's roles: " + userRoles) End If End Using End Sub Sub GetProfileInfo(ByVal cookieContainer As CookieContainer) Dim profileSvc As New ProfileServiceClient() Using New OperationContextScope(DirectCast(profileSvc.InnerChannel, IContextChannel)) SetCookies(OperationContext.Current, cookieContainer) Dim profileData As Dictionary(Of String, Object) = profileSvc.GetPropertiesForCurrentUser(New String() {"FirstName", "LastName", "EmployeeId"}, True) Console.WriteLine("FirstName: " + profileData("FirstName")) Console.WriteLine("LastName: " + profileData("LastName")) Console.WriteLine("EmployeeId: " + profileData("EmployeeId")) End Using End Sub Public Function strEndPtAddr(ByVal service As String) As String Dim endPtAddr As String = "http://" + Host + "/WcfApplicationServices/" + service + ".svc?wsdl" Return endPtAddr End Function Sub Init(ByVal args As String()) If (args.Length = 3) Then 'The host address was passed in , use that. Host = args(2) Else Host = "localhost:8080" End If Dim username As String = args(0) Dim password As String = args(1) Dim result As Boolean Dim binding As BasicHttpBinding = New BasicHttpBinding() Dim endPtAddr As String = strEndPtAddr("MyAuthenSvcWrap") Console.WriteLine("Attempting to connect as username = " + username + vbNewLine _ + "password length = " + password.Length.ToString() + vbNewLine _ + " on server " + Host + vbNewLine _ + "End point address: " + endPtAddr _ ) ' BasicHttpBinding and endpoint are explicitly passed and ignored ' in app.config file. Dim authService As AuthenticationServiceClient = New AuthenticationServiceClient(binding, _ New EndpointAddress(endPtAddr)) Dim cookieContainer As CookieContainer = Nothing Dim customCredential As String = "Not Used by the default membership provider" Dim isPersistent As Boolean = True ' authentication ticket remains valid across sessions. Using New OperationContextScope(authService.InnerChannel) Try result = authService.Login(username, password, customCredential, isPersistent) cookieContainer = GetCookies(OperationContext.Current) Catch enf As EndpointNotFoundException Console.WriteLine(enf.Message) Return End Try End Using If result Then Console.WriteLine("Welcome " + username + ". You have logged in.") GetProfileInfo(cookieContainer) GetUserRoles(cookieContainer) Else Console.WriteLine("We could not validate your credentials.") End If End Sub End Class Sub Main(ByVal args As String()) If (args.Length < 1) Then Console.WriteLine("missing args username password") Return End If Dim mst As MyServiceTst = New MyServiceTst() mst.Init(args) Console.WriteLine("Enter any key to exit.") Console.Read() End Sub End Module
using System; using System.Collections.Generic; using System.Text; using System.ServiceModel; using System.ServiceModel.Activation; using System.ServiceModel.Channels; using System.ComponentModel; using System.Web; using System.Net; class MyServiceTst { string Host { get; set; } CookieContainer GetCookies(OperationContext oc) { HttpResponseMessageProperty httpResponseProperty = (HttpResponseMessageProperty)oc.IncomingMessageProperties[HttpResponseMessageProperty.Name]; if (httpResponseProperty != null) { CookieContainer cookieContainer = new CookieContainer(); string header = httpResponseProperty.Headers[HttpResponseHeader.SetCookie]; if (header != null) { cookieContainer.SetCookies(new Uri(@"http://someuri.tld"), header); } return cookieContainer; } return null; } void SetCookies(OperationContext oc, CookieContainer cookieContainer) { HttpRequestMessageProperty httpRequestProperty = null; if (oc.OutgoingMessageProperties.ContainsKey(HttpRequestMessageProperty.Name)) { httpRequestProperty = oc.OutgoingMessageProperties[HttpRequestMessageProperty.Name] as HttpRequestMessageProperty; } if (httpRequestProperty == null) { httpRequestProperty = new HttpRequestMessageProperty(); oc.OutgoingMessageProperties.Add(HttpRequestMessageProperty.Name, httpRequestProperty); } httpRequestProperty.Headers.Add(HttpRequestHeader.Cookie, cookieContainer.GetCookieHeader(new Uri(@"http://someuri.tld"))); } void GetUserRoles(CookieContainer cookieContainer) { string endPtAddr = strEndPtAddr("MyRoleSvcWrap"); RoleServiceClient roleSvc = new RoleServiceClient(new BasicHttpBinding(), new EndpointAddress(endPtAddr)); using (new OperationContextScope((IContextChannel)roleSvc.InnerChannel)) { SetCookies(OperationContext.Current, cookieContainer); string[] roles = roleSvc.GetRolesForCurrentUser(); if (roles.Length == 0) { Console.WriteLine("User does not belong to any role."); } else { string userRoles = ""; for (int i = 0; i < roles.Length; i++) { userRoles += roles[i] + " "; } Console.WriteLine("User's roles: " + userRoles); } } } void GetProfileInfo(CookieContainer cookieContainer) { string endPtAddr = strEndPtAddr("MyProfileSvcWrap"); ProfileServiceClient profileSvc = new ProfileServiceClient(new BasicHttpBinding(), new EndpointAddress(endPtAddr)); string[] strProfileProps = new string[] { "FirstName", "LastName", "EmployeeId" }; using (new OperationContextScope((IContextChannel)profileSvc.InnerChannel)) { SetCookies(OperationContext.Current, cookieContainer); Dictionary<string, object> profileData = profileSvc.GetPropertiesForCurrentUser(strProfileProps, true); foreach (string sProp in strProfileProps) Console.WriteLine(sProp + ": " + profileData[sProp]); } } public string strEndPtAddr(string service) { string endPtAddr = @"http://" + Host + "/WcfApplicationServices/" + service + ".svc?wsdl"; return endPtAddr; } public void Init(string[] args) { if (args.Length == 3) // The host address was passed in , use that Host = args[2]; else Host = "localhost:8080"; string username = args[0]; string password = args[1]; bool result = false; BasicHttpBinding binding = new BasicHttpBinding(); string endPtAddr = strEndPtAddr("MyAuthenSvcWrap"); Console.WriteLine("Attempting to connect as username = " + username + "\n password length = " + password.Length.ToString() + "\n on server " + Host + "\n" + "\n" + endPtAddr ); // BasicHttpBinding and endpoint are explicitly passed and ignored // in app.config file AuthenticationServiceClient authService = new AuthenticationServiceClient(binding, new EndpointAddress(endPtAddr)); CookieContainer cookieContainer; string customCredential = "Not Used by the default membership provider"; bool isPersistent = true; // authentication ticket remains valid across sessions. using (new OperationContextScope(authService.InnerChannel)) { try { result = authService.Login(username, password, customCredential, isPersistent); cookieContainer = GetCookies(OperationContext.Current); } catch (EndpointNotFoundException enfe) { Console.WriteLine(enfe.Message); if (enfe.InnerException != null && enfe.InnerException.Message != null) Console.WriteLine(enfe.InnerException.Message); return; } } if (result) { Console.WriteLine("Welcome " + username + ". You have logged in."); GetUserRoles(cookieContainer); GetProfileInfo(cookieContainer); } else { Console.WriteLine("We could not validate your credentials."); } } } class Program { static void Main(string[] args) { if (args.Length < 1) { Console.WriteLine("missing args username password [host]"); return; } MyServiceTst mst = new MyServiceTst(); mst.Init(args); Console.WriteLine("Enter any key to exit."); // Console.Read(); } }
Постройте проект.
Доступ к службам приложения
Теперь можно запустить клиентское приложение и использовать службы приложения, которые были предоставлены как часть веб-узла.
Запуск приложения Windows
В командной строке Windows перейдите в каталог консольного приложения.
Введите следующую команду, указав имя и пароль одного из пользователей, созданных ранее в ходе выполнения данного пошагового руководства.
AppSvcClient.exe <userName> <password>
Если учетные данные введены верно, то будет выполнена проверка подлинности, и появится доступ к сведениям о ролях и профиле, связанным с пользователем, под которым выполнен вход.
Следующие действия
Данное пошаговое руководство демонстрирует основные принципы доступа к службам приложения ASP.NET из клиентского приложения, которое способно получать и отправлять сообщения в формате SOAP.
В качестве эксперимента можно протестировать различные дополнительные функциональные возможности службы приложения. Рекомендации для дополнительных исследований:
Необходимо ознакомиться с дополнительными сведениями об использовании служб приложений для клиентов .NET Framework. Дополнительные сведения см. в разделе Общие сведения о службах клиентских приложений.
Следует также ознакомиться со сведениями о Windows Communication Foundation (WCF) и об обмене данными в формате SOAP с клиентом. Дополнительные сведения см. на веб-узле MSDN в разделе Инфраструктура веб-служб XML.
Чтобы получить общее представление о веб-службах, необходимо следующее:
Понимание действий, выполняемых при вызове веб-службы. Дополнительные сведения см. в разделе Anatomy of an XML Web Service Lifetime.
Понимание принципов использования веб-служб. Дополнительные сведения см. в разделе XML Web Service Scenarios.
Необходимо ознакомиться с дополнительными сведениями о службах приложений ASP.NET. Дополнительные сведения см. в разделе AuthenticationServiceLogin().
См. также
Задачи
Практическое руководство. Включение службы проверки подлинности WCF
Практическое руководство. Включение службы роли WCF
Практическое руководство. Включение службы профилей WCF