2010-09-13 30 views
1

Je suis en train d'accéder http://localhost/tempservicehost/tempservice.svc et je reçois l'erreur suivante:déploiement WCF REST Erreur: « ressource n'existe pas »

Error Description: 'Resource does not exist'

This may be because an invalid URI or HTTP method was specified. Please see the service help page for constructing valid requests to the service.

Le plus drôle est que http://localhost/tempservicehost/tempservice.svc/help fonctionne très bien. Non seulement cela, tous mes points finaux fonctionnent bien. J'utilise IIS 7.5 (Win 2008 R2). Application développée avec .NET 4.0

Poster Mis à jour (suivant est le code):

<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 

La config est ici:

<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

Pouvez-vous ajouter votre contrat de service (code définissant les attributs WebGet et WebInvoke pour vos opérations)? –

+0

post mis à jour avec le code entier. Faites-moi savoir si vous avez besoin de plus de code. – user203687

Répondre

2

I Had un problème similaire,

J'ai trouvé que si je naviguais vers une ressource réelle, c'était bien.

par exemple

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

en supposant que vous avez la méthode suivante ainsi

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

ce qui est arrivé ici est que l'erreur type 404 qui est normalement retourné n'a pas été rendu le chemin vous vous y attendez. (En général, vous obtenez un en-tête bleu et une ligne disant point de fin de service ou similaire)

Si vous souhaitez personnaliser vos erreurs il y a une question Custom Error Handling message for Custom WebServiceHost qui explique comment choisir des codes d'erreur sur le chemin à travers et modifier le retour .

+0

J'ai aussi trouvé ça. Mais, je ne pouvais pas me débarrasser de l'erreur. Faites-moi savoir, si vous trouvez une solution pour ce qui précède. – user203687

+0

L'erreur dans ce cas est une erreur légitime. C'est un 404 Not Found (ce qui est vrai car il n'y a pas de ressource chez tempservice, svc) La question devrait maintenant être de savoir comment personnaliser l'erreur. – Bluephlame

+0

Mais, si je supprime le comportement http personnalisé et la fabrique d'hôte personnalisée, je ne rencontre pas cette erreur! – user203687