1

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>
4

1 に答える 1

2

同様の問題がありましたが、

実際のリソースに移動しても問題ないことがわかりました。

例えば

http://localhost/tempservicehost/tempservice.svc/test/

次の方法もあると仮定します

[OperationContract]    
[WebGet(UriTemplate = "/test/")]
public Test TestMethod()
{
  return new Test("Hello world");
}

ここで起こったことは、通常返される標準の 404 エラーが、期待どおりにレンダリングされていないことです。(通常、青いヘッダーと、サービス エンド ポイントなどを示す行が表示されます)

エラーをカスタマイズしたい場合は、カスタム WebServiceHost のカスタム エラー処理メッセージ で、途中でエラー コードを取得して戻り値を変更する方法について説明しています。

于 2010-09-30T03:57:38.413 に答える