Verbindung zwischen dem IIS-App-Pool-Identität und SQL Server
Habe ich entwickelt, eine sehr einfache WCF-Dienst (WCF 4.0) in VS 2012. Ich habe die AdventureWorks2012-Datenbank in SQL Server 2012 und ich bin mit IIS 7 mit .Net 4.0 framework installiert ist.
Wenn ich den Dienst in der lokalen Entwicklung IIS mit VS 2012, alles funktioniert einwandfrei (ich vermute, weil Sie die Verbindungszeichenfolge in der web.config für die website-hosting die .svc wird gesetzt, um die Integrierte Sicherheit verwenden - Der connection-string ist unten)
<add name="AdventureWorksEntities" connectionString="metadata=res://*/ProductsModel.csdl|res://*/ProductsModel.ssdl|res://*/ProductsModel.msl;provider=System.Data.SqlClient;provider connection string="data source=adams_pc;initial catalog=AdventureWorks2012;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework"" providerName="System.Data.EntityClient"/>
Veröffentlicht, wenn ich die website auf meinem lokalen IIS und führen Sie es in die ASP.NET 4.0 Anwendungspool, es scheint, dass keine Verbindung besteht tatsächlich aus der Datenbank (wenn Sie eine Konsole-test-client, der Objekte aus meiner entity-Modell haben keine Daten, die in Ihnen).
Habe ich Benutzer in der AdventureWorks2012-Datenbank mit den Namen der IIS APPPOOL\ASP.NET v4.0 gegeben und dann "dbo".Besitzer Zugriff auf die Datenbank, aber ich bekomme keine Verbindung hergestellt werden.
Was bin ich? Muss ich ändern Sie die Verbindungszeichenfolge auf der hosting-website?
Mehr Informationen:
Wenn ich es lokal (durch Entwicklung server meinte ich die lokale Instanz von IIS ausgeführt wird, wenn ich die Anwendung Debuggen) Informationen aus der Datenbank abgerufen werden und zeigt in der test-Konsole-Anwendung.
Wenn ich mit der Bereitstellung des service und ändern Sie den Verweis in der test-Konsole-Anwendung für die Verwendung des gehosteten WCF-Dienst keine Daten abgerufen werden überhaupt. Die Ausnahme, die ausgelöst wird eine null-Verweis-Ausnahme in meinem test-code, aber das ist, weil keine Daten aufgefüllt in das entity-Modell mein Dienst verwendet. Ich sehe keine Ausnahmen in Bezug auf die Datenbank-Verbindung, aber ich habe nicht bekommen, bis zu dem Punkt lernen, wie Sie den pass Ausnahmen von der Dienstleistung für den Kunden. Ich hatte erwartet, diesen einfachen test zu funktionieren genauso wie das Buch, das ich Arbeit aus habe.
Außerdem ist es etwas anderes was ich tun sollte, arbeiten Sie heraus, was genau der Fehler ist, wenn es um die Herstellung der Datenbank-Verbindung?
Service:
Imports System.Text
Imports System.Linq
Imports System
Imports System.Collections.Generic
Imports System.ServiceModel
Imports System.ServiceModel.Web
Imports System.Runtime.Serialization
Imports ProductsEntityModel
'NOTE: You can use the "Rename" command on the context menu to change the class name "Service" in code, svc and config file together.
'WCF service that implements the service contract
'This implementation performs minimal error checking and exception handling
Public Class ProductsServiceImpl
Implements IProductsService
Public Function ChangeStockLevel(productNumber As String, newStockLevel As Short, shelf As String, bin As Short) As Boolean Implements IProductsService.ChangeStockLevel
'Modify the current stock level of the selected product in the ProductInventory table.
'If the update is successful then return True, otherwise return False.
'The Product and ProductIventory tables are joined over the ProductID column.
Try
'Connect to the AdventureWorks database using the Entity Framework
Using database As New AdventureWorksEntities()
' Find the ProductID for the specified product
Dim qryProductID = (From p In database.Products
Where String.Compare(p.ProductNumber, productNumber) = 0
Select p.ProductID).First
'Find the ProductInventory object that matches the paramters passed into the operation
Dim productInv As ProductInventory = database.ProductInventories.First(Function(pi) String.Compare(pi.Shelf, shelf) = 0 And pi.Bin = bin And pi.ProductID = qryProductID)
'Update the stock level for the ProductInventory object
productInv.Quantity += newStockLevel
'Save the change back to the database
database.SaveChanges()
End Using
Catch ex As Exception
Return False
End Try
Return True
End Function
Public Function CurrentStockLevel(ByVal productNumber As String) As Integer Implements IProductsService.CurrentStockLevel
'Obtain the total stock level for the specified product
'The stock level is calculated by summing the quantity of the product available in all the bins in
'the ProductInventory table
'The Product and ProductInventory tables are joined over the ProductID column.
Dim stockLevel As Integer = 0
Try
'Connect to the AdventureWorks database by using the Entity Framework.
Using database As New AdventureWorksEntities()
stockLevel = (From pi In database.ProductInventories
Join p In database.Products
On pi.ProductID Equals p.ProductID
Where String.Compare(p.ProductNumber, productNumber) = 0
Select CInt(pi.Quantity)).Sum
End Using
Catch ex As Exception
End Try
Return stockLevel
End Function
Public Function GetProduct(productNumber As String) As ProductData Implements IProductsService.GetProduct
'Create a reference to a ProductData object
Dim productData As ProductData = Nothing
Try
'Connect to the AdventureWorks database by using Entity Framework
Using database As New AdventureWorksEntities()
Dim matchingProduct As Product = database.Products.First(Function(p) String.Compare(p.ProductNumber, productNumber) = 0)
productData = New ProductData With {.Name = matchingProduct.Name, .ProductNumber = matchingProduct.ProductNumber, .Color = matchingProduct.Color, .ListPrice = matchingProduct.ListPrice}
End Using
Catch ex As Exception
End Try
Return productData
End Function
Public Function ListProducts() As List(Of String) Implements IProductsService.ListProducts
'Create a list for holding product numbers
Dim productsList As New List(Of String)
Try
'Connect to the AdventureWorks database by uysing the Entity Framework
Using database As New AdventureWorksEntities()
' Fetch the product number of every product in the database
Dim products = From Product In database.Products
Select Product.ProductNumber
productsList = products.ToList
End Using
Catch ex As Exception
End Try
'Return the list of product numbers
Return productsList
End Function
End Class
Schnittstelle:
Imports System.Text
Imports System.Linq
Imports System
Imports System.Collections.Generic
Imports System.ServiceModel
Imports System.ServiceModel.Web
Imports System.Runtime.Serialization
'NOTE: You can use the "Rename" command on the context menu to change the interface name "IService" in both code and config file together.
'The Data Contact describes the details of a Product object passed to client applications (this is a return object).
<DataContract>
Public Class ProductData
<DataMember>
Public Name As String
<DataMember>
Public ProductNumber As String
<DataMember>
Public Color As String
<DataMember>
Public ListPrice As Decimal
End Class
'The Service Contact describes the operations that the WCF service provides (these are the methods available to call)
<ServiceContract>
Public Interface IProductsService
'Get the product number of every product
<OperationContract>
Function ListProducts() As List(Of String)
'Get the details of a single product
<OperationContract>
Function GetProduct(ByVal productNumber As String) As ProductData
'Get the current stock level for a product
<OperationContract>
Function CurrentStockLevel(ByVal productNumber As String) As Integer
'Change the stock level for a product
<OperationContract>
Function ChangeStockLevel(ByVal productNumber As String, ByVal newStockLevel As Short, ByVal shelf As String, ByVal bin As Int16) As Boolean
End Interface
Client:
Imports System.ServiceModel
Imports ProductsClient.ProductsService
Module Module1
Sub Main()
' Create a proxy object and connect to the service
Dim proxy As New ProductsServiceClient()
' Test the operations of the service
' Obtain a list of all the products
Console.WriteLine("Test 1: List all products")
Dim productNumbers As String() = proxy.ListProducts
For Each productNumber As String In productNumbers
Console.WriteLine("Number: {0}", productNumber)
Next
Console.WriteLine()
Console.WriteLine("Test 2: Display the Details of a product")
Dim product As ProductData = proxy.GetProduct("WB-H098")
Console.WriteLine("Number: {0}", product.ProductNumber)
Console.WriteLine("Name: {0}", product.Name)
Console.WriteLine("Color: {0}", product.Color)
Console.WriteLine("Price: {0}", product.ListPrice)
Console.WriteLine()
' Query the stock level of this product
Console.WriteLine("Test 3: Display the stock level of a product")
Dim numInStock As Integer = proxy.CurrentStockLevel("WB-H098")
Console.WriteLine("Number in stock: {0}", numInStock)
Console.WriteLine()
' Modify the stock level of this product
Console.WriteLine("Test 4: Modify the stock level of a product")
If proxy.ChangeStockLevel("WB-H098", 100, "N/A", 0) Then
numInStock = proxy.CurrentStockLevel("WB-H098")
Console.WriteLine("Stock level changed. Current stock level: {0}", numInStock)
Else
Console.WriteLine("Stock level update failed.")
End If
Console.WriteLine()
' Disconnect from the service
proxy.Close()
Console.WriteLine("Press ENTER to finish")
Console.ReadLine()
End Sub
End Module
Und nur für kichert, dies ist die SQL-scirpt habe ich verwendet, um meine Benutzer in der AdventureWorks2012-Datenbank:
USE [AdventureWorks2012]
GO
CREATE USER [IIS APPPOOL\DefaultAppPool] FOR LOGIN [IIS APPPOOL\DefaultAppPool]
GO
EXEC sp_addrolemember N'db_owner', [IIS APPPOOL\DefaultAppPool]
GO
GO
CREATE USER [IIS APPPOOL\ASP.NET v4.0] FOR LOGIN [IIS APPPOOL\ASP.NET v4.0]
GO
EXEC sp_addrolemember N'db_owner', [IIS APPPOOL\ASP.NET v4.0]
GO
Und hier ist das serviceModel Bestandteil der client-app.config, so können Sie die endpoint
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_IProductsService" />
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost/ProductsService/Service.svc" binding="basicHttpBinding"
bindingConfiguration="BasicHttpBinding_IProductsService" contract="ProductsService.IProductsService"
name="BasicHttpBinding_IProductsService" />
</client>
</system.serviceModel>
- Benötigen Sie einige Informationen. Gibt es irgendeine Ausnahme? Wie Sie wissen, dass Ihr service funktioniert auch auf dem development-server? Was ist der Unterschied, wenn Sie host auf dem IIS?
- Mehr Informationen Hinzugefügt werden, wie angefordert.
- Das ist unmöglich zu diagnostizieren, ohne code.
- Ok, der code ist hilfreich? Der Service, das entity-Modell die client-Anwendung?
- Service, client - + service-Schnittstelle.
- Code Hinzugefügt, wie gefordert.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ihrem service code fängt alle Ausnahme, schweigend. Code wie, das ist nicht akzeptabel :).
Debuggen echte Ausnahme führen Sie Ihre visual studio als administrator. Wählen Sie "Debuggen" - > an den Prozess Anhängen -> Überprüfen Sie "Show Prozesse aller Benutzer" -> Wählen Sie "w3wp.exe". Führen Sie Ihre test-app, und warten Sie für die web-service-Ausnahme in visual studio.
Gut, es stellt sich heraus, dass das problem war, dass ich fehlende server-Benutzer für die app-pool. Das SQL-Skript hatte ich gepostet hatte nur erstellt einen Datenbank-Benutzer für die app-pool-Identität, aber es gab keine server-Anmeldung, für die gleiche Identität. Einmal habe ich Hinzugefügt, dass die user (und ich hatte zu Typ IIS APPPOOL\ASP.NET v4.0 manuell und versuchen Sie nicht, um Sie als ein Objekt in der windows-login-Auswahl) alles gut geklappt hat.
Vielen Dank für deine Hilfe, Grzegorz, obwohl es etwas völlig triviales am Ende!