【发布时间】:2020-01-20 10:59:53
【问题描述】:
我在 Visual Studio 中创建了一个 WCF 服务,正如标题中所说,它无法访问 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 };
}
}
使用最后一个 return 语句,应用程序 ClientTestWCF 能够调用 getSupermarche() 方法并获得正确的结果。那我猜问题出在数据库访问上。
此数据库与实体框架一起使用;因为这似乎没有问题(因为上面的最后一个返回有效)我不会在这里展示它。请注意,我用[DataContract] 和[DataMember] 装饰了课程。
服务在 IIS 中发布,在 Windows 中发布,而不是在集成中发布。
这是 Web.config 文件(在服务项目中):
<?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>
编辑:
我忘记了错误,进入客户端 Microsoft 测试应用:
Échec de l'appel du 服务。可能的原因:le service est peut être hors ligne ou inaccessible ; la configuration côté client ne 对应 pas au 代理; le proxy exists n'est pas valide。 Reportez-vous à la trace de la pour pour plus de 详细信息。 Vous pouvez tenter une récupération en démarrant un nouveau proxy, en restaurant la configuration par défaut ou en actualisant le service。
意思是:
服务调用失败。服务可能无法访问,现有代理无效。您可以尝试通过恢复默认配置或更新服务来创建新代理。
这是堆栈跟踪:
Une erreur s'est produite lors de la réception de la réponse HTTP à http://localhost/market8/Service.svc。 La raison peut en être que la liaison de point de terminaison de service n'utilise pas le protocole HTTP。 Cela peut également être dû au fait qu'un contexte de requête HTTP a été ignoré par le serverur (peut-être à cause de l'arrêt du service)。 Pour plus d'informations,consultez les journaux du serverur。
意思是:
http://localhost/market8/Service.svc 调用的 http 应答接收出错,端点可能未使用 HTTP 协议,或者服务器可能忽略 HTTP 请求上下文(原因:服务停止?)。
服务器堆栈跟踪:à System.ServiceModel.Channels.HttpChannelUtilities.ProcessGetResponseWebException(WebException webException, HttpWebRequest 请求, HttpAbortReason abortReason)
一个 System.ServiceModel.Channels.HttpChannelFactory`1.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan 超时)à System.ServiceModel.Channels.RequestChannel.Request(消息消息, TimeSpan 超时)à System.ServiceModel.Dispatcher.RequestChannelBinder.Request(消息 消息,TimeSpan 超时)à System.ServiceModel.Channels.ServiceChannel.Call(字符串动作, Boolean oneway, ProxyOperationRuntime 操作, Object[] ins, Object[] 出局,TimeSpan 超时)à System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall、ProxyOperationRuntime 操作)à System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage 留言)在 [0] 处重新抛出异常:à System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg) à System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(消息数据& msgData, Int32 类型) à IService.getSupermarche() à ServiceClient.getSupermarche()
内部例外:La connexion sous-jacente a été fermée : Une erreur 不注意 s'est produite lors de la réception。一个 (这意味着:底层连接已关闭:接收时发生意外错误)
System.Net.HttpWebRequest.GetResponse() à System.ServiceModel.Channels.HttpChannelFactory`1.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan 超时)
内在例外:Impossible de lire les données de la connexion de 交通 : Une connexion existsante a dû être fermée par l'hôte 遥远。
(这意味着:无法读取传输连接的数据:现有 必须关闭连接)à System.Net.Sockets.NetworkStream.Read(Byte[] 缓冲区, Int32 偏移量,Int32 大小)→ System.Net.PooledStream.Read(Byte[] 缓冲区,Int32 偏移量,Int32 大小)à System.Net.Connection.SyncRead(HttpWebRequest 请求,布尔值 userRetrievedStream, Boolean probeRead)
内部例外: Une connexion existsante a dû être fermée par l'hôte 遥远的
(这意味着:远程主机必须关闭远程连接) à System.Net.Sockets.Socket.Receive(Byte[] buffer, Int32 偏移量,Int32 大小,SocketFlags socketFlags)à System.Net.Sockets.NetworkStream.Read(Byte[] 缓冲区,Int32 偏移量, int32 大小)
服务已部署到 IIS。
编辑 下面是控制台项目中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”作为连接字符串,所以我也将服务连接字符串更改为“sqlserver”,但没有帮助。
编辑 值得注意的是,当 getSupermarche() 方法返回一个人工的 Supermarche 对象时,并没有报错,可以得到预期的结果。 所以问题似乎来自数据库访问,而不是来自 http 配置(除非两者都链接但我不这么认为)。
Linq 问题? 以下是控制台项目中的引用: 以下是服务项目的参考资料:
我没有注意到有问题的想法。
【问题讨论】:
-
那么当它尝试连接时,你会得到什么错误?你能在 SQL Server 的日志中看到连接尝试吗?如果是这样,他们说了什么错误?
-
不幸的是错误不是英文的; Stack Overflow 是一个英语社区(我看到你已经翻译了其中的一部分,但没有翻译其余部分)。
-
您说您的工作应用程序“或多或少”具有相同的代码,但我们无法评估,因为您没有展示它。此外,工作应用程序是否连接到同一个数据库?另外,你试过什么?启用 WCF 跟踪以查看实际异常。很有可能,因为您将 Entity Framework 实体用作 DTO(您不应该),所以您有一个循环引用,因此您的实体无法正确序列化,或者由于延迟加载,您得到了一个“上下文处理”例外。此问题中没有足够的信息来解决此问题;自己研究一下。
-
由于
there was an error at the http answer reception for the http://localhost/market8/Service.svc call,您似乎没有正确配置服务,请检查服务配置和网址。这里is the documentation。您可以使用网络浏览器查看网络服务 URL。 -
我翻译了剩余的法语文本,并在我对问题的编辑中建议错误可能来自数据库访问。
标签: c# sql-server web-services wcf