我正在尝试访问http://localhost/tempservicehost/tempservice.svc,我收到以下错误:
错误说明:'资源没有 存在'
这可能是因为无效的URI或 指定了HTTP方法。请参阅 用于构建的服务帮助页面 有效的服务请求。
有趣的是http://localhost/tempservicehost/tempservice.svc/help工作正常。不仅如此,我的所有终端都工作正常。
我正在使用IIS 7.5(Win 2008 R2)。使用.NET 4.0开发的应用程序
发布更新(以下是代码):
<ServiceContract()>
Public Interface ITestSvc
<OperationContract()>
<Description("")>
<WebInvoke(Bodystyle:=WebMessageBodyStyle.Bare,
Method:="POST",
UriTemplate:="GetCodes")>
Function GetCodes(ByVal oReq As ReqGetCodes) As RespGetCodes
End Interface
Public Class TestSvc
Implements ITestSvc
Public Function GetCodes(ByVal oReq As ReqGetCodes) As RespGetCodes Implements ITestSvc.GetCodes
Dim o As New RespGetCodes
Dim lstGetCodes = New List(Of ClassGetCodes) From {
New ClassGetCodes With {.App_Code = "a1", .SystemFlag = True},
New ClassGetCodes With {.App_Code = "a2", .SystemFlag = False},
New ClassGetCodes With {.App_Code = "a3", .SystemFlag = True},
New ClassGetCodes With {.App_Code = "a4", .SystemFlag = True},
New ClassGetCodes With {.App_Code = "a5", .SystemFlag = False}
}
o.GetCodesArray = lstGetCodes.ToArray
Return o
End Function
End Class
Public Class TestWebHttpBehavior
Inherits WebHttpBehavior
Protected Overrides Sub AddServerErrorHandlers(ByVal endpoint As System.ServiceModel.Description.ServiceEndpoint, ByVal endpointDispatcher As System.ServiceModel.Dispatcher.EndpointDispatcher)
endpointDispatcher.ChannelDispatcher.ErrorHandlers.Clear()
endpointDispatcher.ChannelDispatcher.ErrorHandlers.Add(New TestErrorHandler)
End Sub
End Class
Public Class TestWcfSvcHostFactory
Inherits ServiceHostFactory
Protected Overrides Function CreateServiceHost(ByVal serviceType As Type, ByVal baseAddresses As Uri()) As ServiceHost
Dim result As New WebServiceHost2(serviceType, True, baseAddresses)
Dim sEnableBasicAuth As String = System.Configuration.ConfigurationManager.AppSettings.Get("EnableBasicAuthentication")
If String.IsNullOrEmpty(sEnableBasicAuth) OrElse String.Compare(sEnableBasicAuth, "false", True) <> 0 Then
result.Interceptors.Add(New TestRequestInterceptor(System.Web.Security.Membership.Provider, "Personify Authentication"))
End If
result.Authorization.PrincipalPermissionMode = PrincipalPermissionMode.None
Dim bahavior As New TestWebHttpBehavior With {.AutomaticFormatSelectionEnabled = True}
result.Description.Endpoints(0).Behaviors.Add(bahavior)
Return result
End Function
End Class
Public Class TestRequestInterceptor
Inherits RequestInterceptor
Private m_provider As MembershipProvider
Private m_realm As String
Public Sub New(ByVal provider As MembershipProvider, ByVal realm As String)
MyBase.New(False)
Me.m_provider = provider
Me.m_realm = realm
End Sub
Protected ReadOnly Property Realm() As String
Get
Return m_realm
End Get
End Property
Protected ReadOnly Property Provider() As MembershipProvider
Get
Return m_provider
End Get
End Property
Public Overrides Sub ProcessRequest(ByRef requestContext As RequestContext)
Dim credentials As String() = ExtractCredentials(requestContext.RequestMessage)
If credentials.Length > 0 AndAlso AuthenticateUser(credentials(0), credentials(1)) Then
InitializeSecurityContext(requestContext.RequestMessage, credentials(0))
Else
Dim reply As Message = Message.CreateMessage(MessageVersion.None, Nothing)
Dim responseProperty As New HttpResponseMessageProperty() With {.StatusCode = HttpStatusCode.Unauthorized}
responseProperty.Headers.Add("WWW-Authenticate", String.Format("Basic realm=""{0}""", Realm))
reply.Properties(HttpResponseMessageProperty.Name) = responseProperty
requestContext.Reply(reply)
requestContext = Nothing
End If
End Sub
Private Function AuthenticateUser(ByVal username As String, ByVal password As String) As Boolean
If Provider.ValidateUser(username, password) Then
Return True
End If
Return False
End Function
Private Function ExtractCredentials(ByVal requestMessage As Message) As String()
Dim request As HttpRequestMessageProperty = DirectCast(requestMessage.Properties(HttpRequestMessageProperty.Name), HttpRequestMessageProperty)
Dim authHeader As String = request.Headers("Authorization")
If authHeader IsNot Nothing AndAlso authHeader.StartsWith("Basic") Then
Dim encodedUserPass As String = authHeader.Substring(6).Trim()
Dim encoding__1 As Encoding = Encoding.GetEncoding("iso-8859-1")
Dim userPass As String = encoding__1.GetString(Convert.FromBase64String(encodedUserPass))
Dim separator As Integer = userPass.IndexOf(":"c)
Dim credentials As String() = New String(1) {}
credentials(0) = userPass.Substring(0, separator)
credentials(1) = userPass.Substring(separator + 1)
Return credentials
End If
Return New String() {}
End Function
Private Sub InitializeSecurityContext(ByVal request As Message, ByVal username As String)
Dim principal As New GenericPrincipal(New GenericIdentity(username), New String() {})
Dim policies As New List(Of IAuthorizationPolicy)()
policies.Add(New PrincipalAuthorizationPolicy(principal))
Dim securityContext As New ServiceSecurityContext(policies.AsReadOnly())
If request.Properties.Security IsNot Nothing Then
request.Properties.Security.ServiceSecurityContext = securityContext
Else
request.Properties.Security = New SecurityMessageProperty() With { _
.ServiceSecurityContext = securityContext _
}
End If
End Sub
Private Class PrincipalAuthorizationPolicy
Implements IAuthorizationPolicy
Private m_id As String = Guid.NewGuid().ToString()
Private user As IPrincipal
Public Sub New(ByVal user As IPrincipal)
Me.user = user
End Sub
Public ReadOnly Property Id As String Implements System.IdentityModel.Policy.IAuthorizationComponent.Id
Get
Return Me.m_id
End Get
End Property
Public Function Evaluate(ByVal evaluationContext As System.IdentityModel.Policy.EvaluationContext, ByRef state As Object) As Boolean Implements System.IdentityModel.Policy.IAuthorizationPolicy.Evaluate
evaluationContext.AddClaimSet(Me, New DefaultClaimSet(Claim.CreateNameClaim(user.Identity.Name)))
evaluationContext.Properties("Identities") = New List(Of IIdentity)(New IIdentity() {user.Identity})
evaluationContext.Properties("Principal") = user
Return True
End Function
Public ReadOnly Property Issuer As System.IdentityModel.Claims.ClaimSet Implements System.IdentityModel.Policy.IAuthorizationPolicy.Issuer
Get
Return ClaimSet.System
End Get
End Property
End Class
End Class
配置在这里:
<system.serviceModel>
<services>
<service behaviorConfiguration="TestWcfServiceBehavior"
name="TestServiceLib.TestSvc">
<endpoint address="" binding="webHttpBinding" behaviorConfiguration="EPrestBehavior"
name="EPrest" contract="TestServiceLib.ITestSvc" />
<endpoint address="mex" binding="mexHttpBinding" name="EPmex"
contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<endpointBehaviors>
<behavior name="EPrestBehavior">
<webHttp />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="TestWcfServiceBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
答案 0 :(得分:2)
我有类似的问题,
我发现如果我导航到实际资源就可以了。
例如
http://localhost/tempservicehost/tempservice.svc/test/
假设您还有以下方法
[OperationContract]
[WebGet(UriTemplate = "/test/")]
public Test TestMethod()
{
return new Test("Hello world");
}
这里发生的事情是,通常返回的标准404错误没有按照您期望的方式呈现。 (通常你得到一个蓝色的标题和一条说服务终点或类似的行)
如果您想自定义错误,则会出现问题Custom Error Handling message for Custom WebServiceHost 这解释了如何在通过途中获取错误代码并修改返回。