Чтобы понять концепцию WAS-хостинга, нам необходимо понять, как конфигурируется система и как создается сервисный контракт, позволяющий по-разному связываться с размещенным сервисом.
Прежде всего, включите WCF для не протоколов. Прежде чем мы начнем создавать сервис, нам нужно настроить систему для поддержки WAS. Ниже приведены шаги по настройке WAS:
-
Нажмите «Пуск» → «Панель управления» → «Программы и компоненты» и нажмите «Включить или выключить компоненты Windows» на левой панели.
-
Разверните «Microsoft .Net Framework 3.0» и включите «Активация Windows Communication Foundation HTTP» и «Активация Windows Communication Foundation без HTTP».
-
Далее нам нужно добавить Binding на веб-сайт по умолчанию. В качестве примера, мы свяжем веб-сайт по умолчанию с протоколом TCP. Зайдите в Пуск Меню → Программы → Стандартные. Щелкните правой кнопкой мыши «Командная строка» и выберите «Запуск от имени администратора» из контекстного меню.
-
Выполните следующую команду —
Нажмите «Пуск» → «Панель управления» → «Программы и компоненты» и нажмите «Включить или выключить компоненты Windows» на левой панели.
Разверните «Microsoft .Net Framework 3.0» и включите «Активация Windows Communication Foundation HTTP» и «Активация Windows Communication Foundation без HTTP».
Далее нам нужно добавить Binding на веб-сайт по умолчанию. В качестве примера, мы свяжем веб-сайт по умолчанию с протоколом TCP. Зайдите в Пуск Меню → Программы → Стандартные. Щелкните правой кнопкой мыши «Командная строка» и выберите «Запуск от имени администратора» из контекстного меню.
Выполните следующую команду —
C:\Windows\system32\inetsrv> appcmd.exe set site "Default Web Site" -+bindings.[protocol='net.tcp',bindingInformation='808:*']
Эта команда добавляет привязку сайта net.tcp к веб-сайту по умолчанию, изменяя файл applicationHost.config, расположенный в каталоге «C: \ Windows \ system32 \ inetsrv \ config». Точно так же мы можем добавить различные протоколы на веб-сайт по умолчанию.
Создать WAS Hosted Service
Шаг 1 — Откройте Visual Studio 2008 и нажмите «Создать» → «Веб-сайт» и выберите «Служба WCF» из шаблона и «Местоположение как HTTP», как показано ниже —
Шаг 2 — Создайте договор, создав интерфейс IMathService. Добавьте атрибут ServiceContract к интерфейсу и атрибут OperationContract к объявлению метода.
using System; using System.Collections.Generic; using System.Linq; using System.Runtime.Serialization; using System.ServiceModel; using System.Text; // NOTE: You can use the "Rename" command on the "Refactor" menu to // change the interface name "IService" in both code and config file // together. [ServiceContract] Public interface IMathService { [OperationContract] int Add(int num1, int num2); [OperationContract] int Subtract(int num1, int num2); }
Шаг 3 — Реализация интерфейса IMathService показана ниже —
using System; using System.Collections.Generic; using System.Linq; using System.Runtime.Serialization; using System.ServiceModel; using System.ServiceModel.Web; using System.Text; // NOTE: You can use the "Rename" command on the "Refactor" menu to // change the class name "Service" in code, svc and config file // together. Public class MathService : IMathService { Public int Add(int num1, int num2) { return num1 + num2; } Public int Subtract(int num1, int num2) { return num1 - num2; } }
Шаг 4 — Сервисный файл показан ниже.
<%@ServiceHostLanguage="C#"Debug="true"Service="MathService"CodeBehind="~/App_Code/MathService.cs"%>
Шаг 5 — В файле web.Config создайте конечную точку с привязкой ‘netTcpBinding’, и метаданные службы будут опубликованы с использованием точки обмена метаданными. Поэтому создайте конечную точку обмена метаданными с адресом «mex» и привязкой «mexTcpBinding». Без публикации метаданных службы мы не можем создать прокси, используя адрес net.tcp, например:
svcutil.exe net.tcp://localhost/WASHostedService/MathService.svc).
<?xml version = "1.0" ?> <configuration> <!-- Note: As an alternative to hand editing this file you can use the web admin tool to configure settings for your application. Use the Website->Asp.Net Configuration option in Visual Studio. A full list of settings and comments can be found in machine.config.comments usually located in \Windows\Microsoft.Net\Framework\vx.x\Config --> <configSections> <sectionGroup name = "system.web.extensions" type = "System.Web.Configuration.SystemWebExtensionsSectionGroup, System.Web.Extensions, Version = 3.5.0.0, Culture = neutral, PublicKeyToken = 31BF3856AD364E35"> <sectionGroup name = "scripting" type = "System.Web.Configuration.ScriptingSectionGroup, System.Web.Extensions, Version = 3.5.0.0, Culture = neutral, PublicKeyToken =3 1BF3856AD364E35"> <section name = "scriptResourceHandler" type = "System.Web.Configuration.ScriptingScriptResourceHandlerSection, System.Web.Extensions, Version = 3.5.0.0, Culture = neutral, PublicKeyToken = 31BF3856AD364E35" requirePermission = "false" allowDefinition = "MachineToApplication"/> <sectionGroup name = "webServices" type = "System.Web.Configuration.ScriptingWebServicesSectionGroup, System.Web.Extensions, Version = 3.5.0.0, Culture = neutral, PublicKeyToken = 31BF3856AD364E35"> <section name = "jsonSerialization" type = "System.Web.Configuration.ScriptingJsonSerializationSection, System.Web.Extensions, Version = 3.5.0.0, Culture = neutral, PublicKeyToken = 31BF3856AD364E35" requirePermission = "false" allowDefinition = "Everywhere"/> <section name = "profileService" type = "System.Web.Configuration.ScriptingProfileServiceSection, System.Web.Extensions, Version = 3.5.0.0, Culture = neutral, PublicKeyToken = 31BF3856AD364E35" requirePermission = "false" allowDefinition = "MachineToApplication"/> <section name = "authenticationService" type = "System.Web.Configuration.ScriptingAuthenticationServiceSection, System.Web.Extensions, Version = 3.5.0.0, Culture = neutral, PublicKeyToken = 31BF3856AD364E35" requirePermission = "false" allowDefinition = "MachineToApplication"/> <section name = "roleService" type = "System.Web.Configuration.ScriptingRoleServiceSection, System.Web.Extensions, Version = 3.5.0.0, Culture = neutral, PublicKeyToken = 31BF3856AD364E35" requirePermission = "false" allowDefinition = "MachineToApplication"/> </sectionGroup> </sectionGroup> </sectionGroup> </configSections> <appSettings/> <connectionStrings/> <system.web> <!-- Set compilation debug="true" to insert debugging symbols into the compiled page. Because this affects performance, set this value to true only during development. --> <compilation debug = "true"> <assemblies> <add assembly = "System.Core, Version = 3.5.0.0, Culture = neutral, PublicKeyToken = B77A5C561934E089"/> <add assembly = "System.Web.Extensions, Version = 3.5.0.0, Culture = neutral, PublicKeyToken = 31BF3856AD364E35"/> <add assembly = "System.Data.DataSetExtensions, Version = 3.5.0.0, Culture = neutral, PublicKeyToken = B77A5C561934E089"/> <add assembly = "System.Web.Extensions, Version = 3.5.0.0, Culture = neutral, PublicKeyToken = 31BF3856AD364E35"/> <add assembly = "System.Xml.Linq, Version = 3.5.0.0, Culture = neutral, PublicKeyToken = B77A5C561934E089"/> </assemblies> </compilation> <!-- The <authentication> section enables configuration of the security authentication mode used by ASP.NET to identify an incoming user. --> <authentication mode="Windows"/> <!-- The <customErrors> section enables configuration of what to do if/when an unhandled error occurs during the execution of a request. Specifically, it enables developers to configure html error pages to be displayed in place of a error stack trace. <customErrors mode = "RemoteOnly" defaultRedirect = "GenericErrorPage.htm"> <error statusCode = "403" redirect = "NoAccess.htm" /> <error statusCode = "404" redirect = "FileNotFound.htm" /> </customErrors> --> <pages> <controls> <add tagPrefix = "asp" namespace = "System.Web.UI" assembly = "System.Web.Extensions, Version = 3.5.0.0, Culture = neutral, PublicKeyToken = 31BF3856AD364E35"/> <add tagPrefix = "asp" namespace = "System.Web.UI.WebControls" assembly = "System.Web.Extensions, Version = 3.5.0.0, Culture = neutral, PublicKeyToken = 31BF3856AD364E35"/> </controls> </pages> <httpHandlers> <remove verb = "*" path = "*.asmx"/> <add verb =" *" path =" *.asmx" validate="false" type = "System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version = 3.5.0.0, Culture = neutral, PublicKeyToken = 31BF3856AD364E35"/> <add verb = "*" path = "*_AppService.axd" validate = "false" type = "System.Web.Script.Services.ScriptHandlerFactory,System.Web.Extensions, Version = 3.5.0.0, Culture = neutral, PublicKeyToken = 31BF3856AD364E35"/> <add verb = "GET,HEAD" path = "ScriptResource.axd" type = "System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version = 3.5.0.0, Culture = neutral, PublicKeyToken = 31BF3856AD364E35" validate = "false"/> </httpHandlers> <httpModules> <add name = "ScriptModule" type = "System.Web.Handlers.ScriptModule, System.Web.Extensions, Version = 3.5.0.0, Culture = neutral, PublicKeyToken = 31BF3856AD364E35"/> </httpModules> </system.web> <system.codedom> <compilers> <compiler language = "c#;cs;csharp" extension = ".cs" warningLevel = "4" type = "Microsoft.CSharp.CSharpCodeProvider, System, Version = 2.0.0.0, Culture = neutral, PublicKeyToken = b77a5c561934e089"> <providerOption name = "CompilerVersion" value = "v3.5"/> <providerOption name = "WarnAsError" value = "false"/> </compiler> <compiler language = "vb;vbs;visualbasic;vbscript" extension = ".vb" warningLevel = "4" type = "Microsoft.VisualBasic.VBCodeProvider, System, Version = 2.0.0.0, Culture = neutral, PublicKeyToken = b77a5c561934e089"> <providerOption name = "CompilerVersion" value = "v3.5"/> <providerOption name = "OptionInfer" value = "true"/> <providerOption name = "WarnAsError" value = "false"/> </compiler> </compilers> </system.codedom> <!-- The system.webServer section is required for running ASP.NET AJAX under Internet Information Services 7.0. It is not necessary for previous version of IIS. --> <system.webServer> <validation validateIntegratedModeConfiguration = "false"/> <modules> <remove name = "ScriptModule"/> <add name = "ScriptModule" preCondition = "managedHandler" type = "System.Web.Handlers.ScriptModule, System.Web.Extensions, Version = 3.5.0.0, Culture = neutral, PublicKeyToken = 31BF3856AD364E35"/> </modules> <handlers> <remove name = "WebServiceHandlerFactory-Integrated"/> <remove name = "ScriptHandlerFactory"/> <remove name = "ScriptHandlerFactoryAppServices"/> <remove name = "ScriptResource"/> <add name = "ScriptHandlerFactory" verb = "*" path = "*.asmx" preCondition = "integratedMode" type = "System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version = 3.5.0.0, Culture = neutral, PublicKeyToken = 31BF3856AD364E35"/> <add name = "ScriptHandlerFactoryAppServices" verb = "*" path = "*_AppService.axd" preCondition = "integratedMode" type = "System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version = 3.5.0.0, Culture = neutral, PublicKeyToken = 31BF3856AD364E35"/> <add name = "ScriptResource" preCondition = "integratedMode" verb = "GET,HEAD" path = "ScriptResource.axd" type = "System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version = 3.5.0.0, Culture = neutral, PublicKeyToken = 31BF3856AD364E35"/> </handlers> <!-- To browse web app root directory during debugging, set the value below to true. Set to false before deployment to avoid disclosing web app folder information. --> <directoryBrowse enabled="true"/> </system.webServer> <runtime> <assemblyBinding appliesTo = "v2.0.05727" xmlns = "urn:schemas-microsoft-com:asm.v1"> <dependentAssembly> <assemblyIdentity name = "System.Web.Extensions" publicKeyToken = "31bf3856ad364e35"/> <bindingRedirect oldVersion = "1.0.0.0-1.1.0.0" newVersion = "3.5.0.0"/> </dependentAssembly> <dependentAssembly> <assemblyIdentity name = "System.Web.Extensions.Design" publicKeyToken = "31bf3856ad364e35"/> <bindingRedirect oldVersion = "1.0.0.0-1.1.0.0" newVersion = "3.5.0.0"/> </dependentAssembly> </assemblyBinding> </runtime> <system.serviceModel> <services> <service behaviorConfiguration = "ServiceBehavior" name = "Service"> <endpoint address = "" binding = "basicHttpBinding" contract = "IMathService"> <identity> <dns value = "localhost" /> </identity> </endpoint> <endpoint address = "mex" binding = "mexHttpBinding" contract = "IMetadataExchange"/> </service> </services> <behaviors> <serviceBehaviors> <behavior name = "ServiceBehavior"> <!-- To avoid disclosing metadata information, set the value below to false before deployment. --> <serviceMetadata httpGetEnabled="true"/> <!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information --> <serviceDebug includeExceptionDetailInFaults="false"/> </behavior> </serviceBehaviors> </behaviors> </system.serviceModel> </configuration>
Разрешить разные привязки к размещенной службе
-
Перейдите в меню Пуск → Программы → Стандартные. Щелкните правой кнопкой мыши «Командная строка» и выберите «Запуск от имени администратора» из контекстного меню.
-
Выполните следующую команду —
Перейдите в меню Пуск → Программы → Стандартные. Щелкните правой кнопкой мыши «Командная строка» и выберите «Запуск от имени администратора» из контекстного меню.
Выполните следующую команду —
C:\Windows\system32\inetsrv>appcmd set app "Default Web Site/WASHostedService" /enabledProtocols:http,net.tcp
Это даст следующий результат —