Типовий SOAP/WSDL сервіс.
Це один з найпоширеніших типів проектів, які я роблю, зоб вивести дані з бази у публічний простір. У мене є декілька описів проектів такого ж типу - B2B-Сервисы с криптографическим залогиниванием (для клиентской и серверной интеграции)., Конфиги WCF-сервисов, обеспечивающие совместимость с JAVA, PHP, FLEX., часто я просто використовую цей тип проектів, щоб зачепитися на відстані за базу, наприклад у ось таких десктопних програмах - Складська прога на WCF-сервісах зі сканером..
Водночас даний проєкт є екстремально простим, бо з одного боку він побудований на Linq-to-SQL, а з іншого боку на процедурах, тому він був зроблений, що називається за годину. Але дуже добре працює, тому я вирішив його описати з кодом.
Ось так цей проєкт працює на моєї девелоперської машині.
На сервері він працює точно так же, але має обмеження по IP-адресам, з яких можна користуватися цім сервісом.
Цей проєкт екстремально простий та корисний, саме тому я про нього й розповідаю. Починається він с мапера LINQ-TO-SQL, у якому я просто зробив врапери для виклику п'яти процедур.
Потім я описав усі інтерфейси у окремому файлі, заздалегідь пристосованому для опису інтерфейсів цього типа проєкту.
1: ' NOTE: You can use the "Rename" command on the context menu to change the interface name "IService1" in both code and config file together.
2: <ServiceContract()>
3: Public Interface IService1
4:
5: <OperationContract()>
6: Function Test(ByVal value As Integer) As String
7:
8: <OperationContract()>
9: Function GetGountry() As System.Collections.Generic.IEnumerable(Of CountryOut)
10:
11: <OperationContract()>
12: Function GetCity() As System.Collections.Generic.IEnumerable(Of CityOut)
13:
14: <OperationContract()>
15: Function GetHotel() As System.Collections.Generic.IEnumerable(Of HotelOut)
16:
17: <OperationContract()>
18: Function GetMentionsByHotelID(HotelID As String) As System.Collections.Generic.IEnumerable(Of Integer)
19:
20: <OperationContract()>
21: Function GetOneMentionByNum(Num As Integer) As System.Collections.Generic.IEnumerable(Of MentionOut)
22:
23: End Interface
24:
25: ' Use a data contract as illustrated in the sample below to add composite types to service operations.
26:
27: <DataContract()>
28: Public Class CountryOut
29:
30: <DataMember()>
31: Public Property CountryID() As String
32:
33: <DataMember()>
34: Public Property CountryName() As String
35: End Class
36:
37: <DataContract()>
38: Public Class CityOut
39:
40: <DataMember()>
41: Public Property CityID() As String
42:
43: <DataMember()>
44: Public Property CityName() As String
45:
46: <DataMember()>
47: Public Property CountryID() As String
48: End Class
49:
50:
51: <DataContract()>
52: Public Class HotelOut
53:
54: <DataMember()>
55: Public Property HotelID() As String
56:
57: <DataMember()>
58: Public Property HotelName() As String
59:
60: <DataMember()>
61: Public Property CountryID() As String
62:
63: <DataMember()>
64: Public Property CityID() As String
65: End Class
66:
67:
68: <DataContract()>
69: Public Class MentionOut
70:
71: <DataMember()>
72: Public Property Num() As Integer
73:
74: <DataMember()>
75: Public Property HotelID() As String
76:
77: <DataMember()>
78: Public Property Stamp() As DateTime
79:
80: <DataMember()>
81: Public Property Vrema() As String
82:
83: <DataMember()>
84: Public Property Title() As String
85:
86: <DataMember()>
87: Public Property Text1() As String
88:
89: <DataMember()>
90: Public Property CNT() As String
91:
92: <DataMember()>
93: Public Property Autor() As String
94: End Class
А реалізація інтерфейсів, завдяки використанню LINQ-to-SQL виглядає навіть простіше, ніж опис інтерфейсів.
1: <Activation.AspNetCompatibilityRequirements(RequirementsMode:=Activation.AspNetCompatibilityRequirementsMode.Allowed)> _
2: Public Class Service1
3: Implements IService1
4:
5:
6: Public Sub New()
7: End Sub
8:
9:
10: Public Function Test(ByVal value As Integer) As String Implements IService1.Test
11: Return String.Format("You entered: {0}", value)
12: End Function
13:
14:
15:
16: Public Function GetGountry() As System.Collections.Generic.IEnumerable(Of CountryOut) Implements IService1.GetGountry
17: Dim db1 As New V3DataContext
18: Dim X = (db1.GetCountrySoap).ToList
19: Dim Z As New System.Collections.Generic.List(Of CountryOut)
20: For Each Y In X
21: Z.Add(New CountryOut With {.CountryID = Y.CountryID, .CountryName = Y.Country})
22: Next
23: Return Z
24: End Function
25:
26: Public Function GetCity() As System.Collections.Generic.IEnumerable(Of CityOut) Implements IService1.GetCity
27: Dim db1 As New V3DataContext
28: Dim X = (db1.GetCitySoap).ToList
29: Dim Z As New System.Collections.Generic.List(Of CityOut)
30: For Each Y In X
31: Z.Add(New CityOut With {.CityID = Y.CityID, .CityName = Y.City, .CountryID = Y.CountryID})
32: Next
33: Return Z
34: End Function
35:
36: Public Function GetHotel() As System.Collections.Generic.IEnumerable(Of HotelOut) Implements IService1.GetHotel
37: Dim db1 As New V3DataContext
38: Dim X = (db1.GetHotelSoap).ToList
39: Dim Z As New System.Collections.Generic.List(Of HotelOut)
40: For Each Y In X
41: Z.Add(New HotelOut With {.HotelID = Y.HotelID, .HotelName = Y.Hotel, .CityID = Y.CityID, .CountryID = Y.CountryID})
42: Next
43: Return Z
44: End Function
45:
46:
47: Public Function GetMentionsByHotelID(HotelID As String) As System.Collections.Generic.IEnumerable(Of Integer) Implements IService1.GetMentionsByHotelID
48: Dim db1 As New V3DataContext
49: Dim X = (db1.GetMentionIDsSoap(HotelID)).ToList
50: Dim Z As New System.Collections.Generic.List(Of Integer)
51: For Each Y In X
52: Z.Add(Y.ID)
53: Next
54: Return Z
55: End Function
56:
57: Public Function GetOneMentionByNum(Num As Integer) As System.Collections.Generic.IEnumerable(Of MentionOut) Implements IService1.GetOneMentionByNum
58: Dim db1 As New V3DataContext
59: Dim X = (db1.GetOneMentionSoap(Num)).ToList
60: Dim Z As New System.Collections.Generic.List(Of MentionOut)
61: For Each Y In X
62: Z.Add(New MentionOut With {.Num = Y.ID, .HotelID = Y.HotelID, .Stamp = Y.Stamp, .Vrema = Y.Vrema, .Title = Y.Title, .Text1 = Y.Text1, .CNT = Y.CNT, .Autor = Y.Autor})
63: Next
64: Return Z
65: End Function
66: End Class
Все що залишилося, щоб цей пазл склався - це конфіг. У данному випадку він виглядає ось так.
1: <?xml version="1.0" encoding="UTF-8"?>
2: <configuration>
3: <connectionStrings>
4: <add name="V3ConnectionString" connectionString="Data Source=XXX.XXX.XXX.XXX;Initial Catalog=YYYYYYYYY;User ID=ZZZZZZZZZ;Password=VVVVVVVVVVVV" providerName="System.Data.SqlClient" />
5: <add name="V3ConnectionString1" connectionString="Data Source=XXX.XXX.XXX.XXX;Initial Catalog=YYYYYYYYY;Persist Security Info=True;User ID=ZZZZZZZZZ;;Password=VVVVVVVVVVVV" providerName="System.Data.SqlClient" />
6: </connectionStrings>
7: <appSettings>
8: <add key="1" value="1" />
9: </appSettings>
10: <system.web>
11: <!-- <customErrors mode="Off" />-->
12: <compilation debug="true" strict="false" explicit="true" targetFramework="4.0" />
13: <authentication mode="Forms" />
14: </system.web>
15: <system.serviceModel>
16: <client>
17: <endpoint address="http://mention.votpusk.ru/Service1.svc" binding="basicHttpBinding" bindingConfiguration="MyBinding0" contract="Mention.IService1" />
18: </client>
19: <services>
20: <service behaviorConfiguration="debug" name="Mention.Service1">
21: <clear />
22: <endpoint address="http://mention.votpusk.ru/Service1.svc" binding="basicHttpBinding" bindingConfiguration="MyBinding0" contract="Mention.IService1" />
23: <host>
24: <timeouts closeTimeout="00:10:00" openTimeout="00:10:00" />
25: </host>
26: </service>
27: </services>
28: <bindings>
29: <basicHttpBinding>
30: <binding name="MyBinding0" closeTimeout="00:10:00" openTimeout="00:10:00" sendTimeout="00:25:00" maxBufferPoolSize="20000000" maxBufferSize="20000000" maxReceivedMessageSize="20000000">
31: <readerQuotas maxDepth="32" maxStringContentLength="20000000" maxArrayLength="20000000" maxBytesPerRead="20000000" maxNameTableCharCount="20000000" />
32: <security>
33: <transport clientCredentialType="None" />
34: </security>
35: </binding>
36: </basicHttpBinding>
37: </bindings>
38: <behaviors>
39: <serviceBehaviors>
40: <behavior name="debug">
41: <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
42: <serviceMetadata httpGetEnabled="true" />
43: <!-- 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 -->
44: <serviceDebug includeExceptionDetailInFaults="true" />
45: </behavior>
46: </serviceBehaviors>
47: </behaviors>
48: <serviceHostingEnvironment multipleSiteBindingsEnabled="false" aspNetCompatibilityEnabled="true" />
49: </system.serviceModel>
50: <system.webServer>
51: <modules runAllManagedModulesForAllRequests="true" />
52: <defaultDocument>
53: <files>
54: <remove value="Default.htm" />
55: <remove value="Default.asp" />
56: <remove value="index.htm" />
57: <remove value="index.html" />
58: <remove value="iisstart.htm" />
59: <remove value="default.aspx" />
60: </files>
61: </defaultDocument>
62: <staticContent>
63: <mimeMap fileExtension=".svc" mimeType="application/octet-stream" />
64: </staticContent>
65: </system.webServer>
66:
67: </configuration>
Ще можна подивитися у цьому проекту на бінарнік, що викладається на хостинг, бо в ньому є усі визначення LINQ-To-SQL та інтерфейсів сервісів.
More:
- How Linux Net Core 3.1 daemon (in VB.NET) can read/write data from/to ancient MS SQL 2005
- How to make WCF service public with Visual Studio, add SSL and debug WCF SSL REST service.
- Start WCF service as REST
- Складська прога на WCF-сервісах зі сканером.
- Increase WcfService Request StringContentLength
- Protect WCF service by password
- WCF_CLIENT - клиент Web-сервиса
- Создание асинхронного прокси для обращения к WCF средствами Adobe flex builder.
- JAVA-клиенты Windows Communication Foundation.
- Конфиги WCF-сервисов, обеспечивающие совместимость с JAVA, PHP, FLEX.