Служба WCF не может получить доступ к базе данных SQL Server, в то время как консольный проект может - PullRequest
0 голосов
/ 20 января 2020

Я создал службу WCF в Visual Studio и, как сказано в заголовке, он не может получить доступ к базе данных SQL Server, в то время как консольный проект, построенный с более или менее одинаковым кодом, может.

Вот интерфейс IService:

[ServiceContract]
public interface IService
{
    [OperationContract]
    Supermarche getSupermarche();
}

Вот реализация метода:

public class Service : IService
{
    public Supermarche getSupermarche()
    {
        //récupération en base
        Model.Supermarche supermarche = null;

        using (var ctx2 = new MarketContext("sqlserverPersonalId"))
        {
            supermarche = ctx2.Supermarches.First<Model.Supermarche>();
        }

        return supermarche;

        //return new Supermarche() { SupermarcheId = 5, Magasins = null };
    }
}

С последним оператором возврата приложение ClientTestWCF может вызовите метод getSupermarche(), и он получит правильный результат. Тогда я предполагаю, что проблема связана с доступом к базе данных.

Эта база данных используется с Entity Framework; так как, похоже, с этим проблем нет (так как работает последнее возвращение выше), я не буду показывать это здесь. Обратите внимание, что я украсил классы [DataContract] и [DataMember].

Сервис публикуется в IIS, Windows, а не интегрированный.

Вот Файл Web.config (в проекте Service):

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <configSections>
        <section name="entityFramework"
                 type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
                requirePermission="false"/>
    </configSections>

    <appSettings>
        <add key="aspnet:UseTaskFriendlySynchronizationContext" value="true"/>
    </appSettings>
    <system.web>
        <compilation debug="false" targetFramework="4.7.2"/>
        <httpRuntime targetFramework="4.7.2"/>
    </system.web>
    <system.serviceModel>
        <behaviors>
            <serviceBehaviors>
                <behavior>
                    <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
                    <serviceDebug includeExceptionDetailInFaults="true"/>
                </behavior>
            </serviceBehaviors>
        </behaviors>
        <services>
            <service name="Service">
                <endpoint address="" 
                          binding="basicHttpBinding" 
                          contract="IService"/>
                <host>
                    <baseAddresses>
                        <add baseAddress="http://localhost:8080"/>
                    </baseAddresses>
                </host>
            </service> 
        </services>
        <protocolMapping>
            <add binding="basicHttpBinding" scheme="http"/>
        </protocolMapping>    
        <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true"/>
    </system.serviceModel>
    <system.webServer>
        <modules runAllManagedModulesForAllRequests="true"/>
            <directoryBrowse enabled="true"/>
            <handlers>
                <add name="serviceHandler" verb="*" path=".svc"
                     type="System.ServiceModel.Activation.HttpHandler, System.ServiceModel, Version=3.0.0.0, Culture=neutral,PublicKeyToken=31bf3856ad364e35"/>
            </handlers>
      </system.webServer>
      <entityFramework>
          <providers>
              <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer"/>
          </providers>
      </entityFramework>
      <connectionStrings>
          <add name="sqlserver" 
               connectionString="Data Source=xxx\SQLEXPRESS;Integrated Security=True;Connect Timeout=90;Encrypt=False;TrustServerCertificate=False;ApplicationIntent=ReadWrite;MultiSubnetFailover=False;Initial Catalog=Market" 
               providerName="System.Data.SqlClient"/>
          <add name="sqlserverPersonalId" 
               connectionString="Data Source=xxx\SQLEXPRESS;Initial Catalog=Market;User ID=xxx;Password=xxx;Connect Timeout=90;Encrypt=False;TrustServerCertificate=False;ApplicationIntent=ReadWrite;MultiSubnetFailover=False" 
               providerName="System.Data.SqlClient"/>
      </connectionStrings>
</configuration>

EDIT:

Я забыл ошибку, попал в клиентское тестовое приложение Microsoft:

Эх c де ла апел дю сервис. Возможные причины: служба недоступна; недоступна; Конфигурация клиента не соответствует pas proxy; le proxy existing n'est pas valide. Репортаж о происхождении и подробности. Вы можете воспользоваться услугами по восстановлению и настройке прокси-сервера, с настройкой ресторана в режиме реального времени.

это означает:

Ошибка вызова службы. может быть недоступен, существующий прокси-сервер недействителен. Вы можете попытаться создать новый прокси-сервер, восстановив конфигурацию по умолчанию или обновив службу.

Вот трассировка стека:

Самый лучший продукт для ответа HTTP * http://localhost/market8/Service.svc. Разъяснение подлинности и связи с протоколом HTTP. Cela peut également étre d'u fait qu'un contexttequ de dequête HTTP été ignoré par le serveur (peut-étre â € œ de de l'arrêt du service). Pour plus d'informations, consulttez les journaux du serveur.

это означает:

Произошла ошибка при получении ответа http для http://localhost/market8/Service.svc вызов, конечная точка может не использовать протокол HTTP или контекст запроса HTTP может игнорироваться сервером (причина: служба остановлена?).

Трассировка стека сервера: à System.ServiceModel.Channels. HttpChannelUtilities. TimeSpan timeout) à System.ServiceModel.Dispatcher.RequestChannelBinder.Request (сообщение-сообщение, TimeSpan timeout) à System.ServiceModel.Channels.ServiceChannel.Call (Строковое действие, логическое одностороннее, ProxyOperationRuntime, Object [] ins, Object []] TimeSpan timeout) à Sys tem.ServiceModel.Channels.ServiceChannelProxy.InvokeService (метод IMethodCallMessageCall, операция ProxyOperationRuntime) à System.ServiceModel.Channels.ServiceChannelProxy.Invoke (сообщение IMessage) * 1055. Время восстановления 0: время восстановления: 0. Proxies.RealProxy.HandleReturnMessage (IMessage reqMsg, IMessage retMsg) à System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke (MessageData & msgData, тип Int32) à IService.getSupermarche () 1058Supermarche () 10SU Исключение: La connectxion sous-jacente a et fermée: Une erreur невнимательно к лучшему продукту Lors de La Réception. à (это означает: основное соединение было закрыто: на приеме произошла непредвиденная ошибка)

System. Net .HttpWebRequest.GetResponse () à System.ServiceModel.Channels.HttpChannelFactory`1.HttpRequestChannel. HttpChannelRequest.WaitForReply (TimeSpan timeout)

Внутреннее исключение: Невозможно перевести связь с транспортом: несоответствие существует в течение нескольких дней.
(это означает, что нет пути к читать данные транспортного соединения: существующее соединение должно быть закрыто)

à System. Net .Sockets.NetworkStream.Read (буфер Byte [], смещение Int32, размер Int32) à System. Net .PooledStream.Read (буфер Byte [], смещение Int32, размер Int32) à System. Net .Connection.SyncRead (запрос HttpWebRequest, логический userRetrievedStream, логический probeRead)

Внутреннее исключение: существует соединение Une d'têtre fermée par l'hôte distant
(это означает: удаленное соединение должно было закрывать удаленное соединение) à System. Net .Sockets.Socket.Receive (буфер Byte [], смещение Int32, Int32 size, SocketFlags socketFlags) à System. Net .Sockets.NetworkStream.Read (буфер Byte [], смещение Int32, размер Int32)

Служба развернута yed to IIS.

EDIT Вот код метода main () в консольном проекте:

static void Main(string[] args)
        {
            using (var ctx = new MarketContext("sqlserver"))
            {
                new MyDataInitializer().InitializeDatabase(ctx);

                //var produitMagasin = new ProduitMagasin() { Nom = "Pommes", Quantite = 10 };
                //ctx.ProduitsMagasin.Add(produitMagasin);

                //var rayon1 = new Rayon() { Nom = "Fruits & Légumes", Produits = new List<ProduitMagasin> { produitMagasin } };
                //ctx.Rayons.Add(rayon1);

                var produitMagasin1 = new ProduitMagasin() { Nom = "Pommes", Quantite = 10 };
                var produitMagasin2 = new ProduitMagasin() { Nom = "Poires", Quantite = 5 };
                var rayon1 = new Rayon() { Nom = "fruits & légumes", Produits = new List<ProduitMagasin>() { produitMagasin1, produitMagasin2 } };
                var magasin1 = new Magasin() { Rayons = new List<Rayon>() { rayon1 } };
                var supermarche1 = new Supermarche() { Magasins = new List<Magasin> { magasin1 } };
                ctx.Supermarches.Add(supermarche1);

                ctx.SaveChanges();

                Console.WriteLine("Programme exécuté");
                Console.ReadLine();

           }
        }

Я использую "sqlserver" в качестве connectionString, поэтому я изменил подключение службы Строка в "sqlserver" тоже, но это не помогло.

EDIT Стоит заметить, что когда метод getSupermarche () возвращает искусственный объект Supermarche, ошибки нет, и я могу получить ожидаемый результат. Таким образом, проблема, похоже, связана с доступом к базе данных, а не из конфигурации http (если оба не связаны, но я так не думаю).

Linq проблема? Вот ссылки в консольном проекте: console project's references, а вот ссылки на сервисный проект: service project's references

Я не заметил проблемы мысль.

1 Ответ

0 голосов
/ 20 января 2020

решено!

фактически, с помощью визуального отладчика и локального запуска службы (с помощью приложения WCFTestClient.exe) я увидел, что вызов контекста, а именно

        using (var ctx2 = new MarketContext("sqlserver"))
        {
            var sm = ctx2.Supermarches.First();

            return sm;
        }

создает переменную sm типа: System.Data.DynamicProxies.Supermarche_xxx, и я полагаю, что это делает службу cra sh. затем я искал и нашел его: Почему EF возвращает прокси-класс вместо фактической сущности? , а затем добавил

ctx2.Configuration.ProxyCreationEnabled = false;

перед извлечением данных, и это сработало.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...