2012-11-05 5 views
15

이 문제점이있는 너트입니다. 나는 2 개의 프로젝트가있는 솔루션을 가지고 있는데, 그 중 하나는 jquery ajax 호출을 사용하는 평범한 구식 html과 다른 하나는 WCF 서비스입니다. html 페이지는 json 문자열을 가져 와서 표시 목적으로 사용하기 위해 WCF 서비스에 대한 ajax 호출을 발행합니다.WCF 오류 : 405 메서드가 허용되지 않습니다.

이제는 디버그 모드에서 실행될 때마다 html 페이지와 WCF가 서로 다른 포트로 시작됩니다. 그리고 이것은 테스트를 수행 할 때 (즉, 파이어 폭스에서 호출 유형 = OPTIONS와 함께 405 메소드가 허용되지 않는 오류가 발생하는) 크로스 발생 문제를 발생시킵니다. 내 아약스 스크립트에서 호출 메소드를 세 번 확인하면 WCF 서비스는 동일합니다 (GET).

google을 검색했지만 확장 프로그램을 설치하거나 IIS에서 일부 구성을 수행해야한다는 것을 알았습니다. IIS에서 내가 수행하는 작업이 간단하기 때문에 성가신 것으로 나타났습니다. 하나의 예에 따라, 내 Web.config의에서 다음과 같은 구성에 추가 싶지만 그것은 작동하지 않았다

<system.serviceModel> 
    <bindings> 
     <webHttpBinding> 
     <binding name="crossDomain" crossDomainScriptAccessEnabled="true" /> 
     </webHttpBinding> 
    </bindings> 
    <behaviors> 
     <endpointBehaviors> 
     <behavior name="MobileService.webHttpBehavior"> 
      <webHttp /> 
     </behavior> 
     </endpointBehaviors> 
     <serviceBehaviors> 
     <behavior name="MyServiceBehavior"> 
      <serviceMetadata httpGetEnabled="true" /> 
      <serviceDebug includeExceptionDetailInFaults="true"/> 
     </behavior> 
     </serviceBehaviors> 
    </behaviors> 
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" /> 
    <services> 
     <service name="MobileService.SimpleMemberInfo" behaviorConfiguration="MyServiceBehavior"> 
     <endpoint address="" binding="webHttpBinding" contract="MobileService.IMemberInfo" bindingConfiguration="crossDomain" behaviorConfiguration="MobileService.webHttpBehavior"> 
     </endpoint> 
     </service> 
    </services> 
    </system.serviceModel> 
    <system.webServer> 
    <httpProtocol> 
     <customHeaders> 
     <add name="Access-Control-Allow-Origin" value="*" /> 
     <add name="Access-Control-Allow-Methods" value="GET" /> 
     <add name="Access-Control-Allow-Headers" value="Content-Type, Accept" /> 
     </customHeaders> 
    </httpProtocol> 
    <modules runAllManagedModulesForAllRequests="true"/> 
    <directoryBrowse enabled="true"/> 
    </system.webServer> 

어떤 생각이 성가신 문제를 제거 할 수 있습니다 중 하나를?

편집 : 그냥 내가 WCF 코드에 추가 VS 스튜디오 2012

와 함께 제공 IIS Express를 사용하여 디버그 및 업데이트의 Web.config를하고 있는데, 추가

[ServiceContract] 
public interface IMemberInfo 
{ 
    [WebInvoke(Method = "GET", 
      BodyStyle = WebMessageBodyStyle.Wrapped, 
      ResponseFormat = WebMessageFormat.Json 
    )] 
    [OperationContract] 
    string GetMemberInfoById(); 
    // TODO: Add your service operations here 
} 

내 스크립트 :

$(document).ready(function() { 
    $.ajax("http://localhost:32972/SimpleMemberInfo.svc/GetMemberInfoById", { 
     cache: false, 
     beforeSend: function (xhr) { 
      $.mobile.showPageLoadingMsg(); 
     }, 
     complete: function() { 
      $.mobile.hidePageLoadingMsg(); 
     }, 
     contentType: 'application/json', 
     dataType: 'json', 
     type: 'GET', 
     error: function() { 
      alert('Something awful happened'); 
     }, 
     success: function (data) { 
      var s = ""; 

      s += "<li>" + data + "</li>"; 
      $("#myList").html(s); 

     } 
    }); 
}); 
+0

WebInvoke(Method = "POST") 이 링크는 http://stackoverflow.com/questions/2202500/wcf-service-405-method-not-allowed-exception – Mihai

+0

감사합니다 도움이 될 수 있습니다. 시도했지만 작동하지 않았습니다. – ipohfly

+0

ops ok ...하지만 답변이 없으면 가장 가까운 것을 골라야합니까? – ipohfly

답변

8

당신은 라운드 t을 얻기 위해 크로스 도메인 호출에 대해 JSONP를 사용할 필요가 그는 브라우저 제한 사항을 적용하고 crossDomainScriptAccessEnabled으로 web.config를 업데이트하여 서버 라운드를 얻습니다. 여기에 좋은 예가 있습니다 : how to avoid cross domain policy in jquery ajax for consuming wcf service?

GET 요청에 문제가있을 수 있습니다. 수정이 여기에 설명보십시오 :

<bindings> 
    <webHttpBinding> 
    <binding name="crossDomain" crossDomainScriptAccessEnabled="true" /> 
    </webHttpBinding> 
</bindings> 
<behaviors> 
    <endpointBehavior> 
    <behavior name="restBehavior"> 
     <webHttp /> 
    </behavior> 
    </endpointBehavior> 
    <serviceBehavior>   
    <behavior name="MyServiceBehavior"> 
     <serviceMetadata httpGetEnabled="true" /> 
     <serviceDebug includeExceptionDetailInFaults="true"/> 
    </behavior> 
    </serviceBehavior> 
</behaviors> 
<services> 
    <service name="..." behaviorConfiguration="MyServiceBehavior"> 
    <endpoint address="" binding="webHttpBinding" bindingConfiguration="crossDomain" 
       contract="..." behaviorConfigurations="restBehavior" /> 
    </service> 
</services> 

이 (webHttp 호출을 허용하는 서비스 및 엔드 포인트 모두가 행동을 부착 한 것을 참고 : Making a WCF Web Service work with GET requests

를 전부, 당신은 이런 식으로 뭔가를 보이는 Web.config를 원하는 httpGet 호출이 있고 바인딩에 명시 적으로 사용 설정된 crossDomain 액세스가 있음을 나타냄).

... 이런 식으로 장식 된 서비스 방법 :

[ServiceContract] 
public interface IMyService 
{ 
    [WebGet] // Required Attribute to allow GET 
    [OperationContract] 
    string MyMethod(string MyParam); 
} 

... 그리고 JSONP를 사용하여 클라이언트 전화 :

<script type="text/javascript"> 
$(document).ready(function() { 
    var url = "..."; 
    $.getJSON(url + "?callback=?", null, function(result) { // Note crucial ?callback=? 
     // Process result 
    }); 
}); 
</script> 
+0

감사합니다. 그냥 시도했지만 작동하지 않았다면 클라이언트 측 예제에 대한 링크가 죽었습니다. 내 web.config에 crossDomain 바인딩을 추가하려고했지만 작동하지 않았습니다. – ipohfly

+0

JSONP에 대한 Google 또는 검색은 다음과 같습니다. - http://stackoverflow.com/questions/2681466/jsonp-with-jquery와 같은 많은 예제가 있습니다. 서버 측만 수정하면 작동하지 않습니다. – JcFx

+0

또한 WCF 코드를 보여줄 수 있습니까? 웹에서 WebGet을 허용하는 것 외에도.위의 예제에 따라 Config를 사용하면 WCF 메서드를 올바른 특성으로 꾸밀 필요가 있습니다. – JcFx

7

그러나 그 옛날 스레드,하지만 난 추가 싶습니다 내 내가 직면 한 문제와 CORS 작업을 위해 얻은 해답에 대해 의견을 말하십시오. 다음 환경에서 웹 서비스를 개발 중입니다.

  1. WCF 웹 서비스.
  2. .NET 3.5 프레임 워크.
  3. 기존 asp.net 웹 사이트에 wcf 웹 서비스를 추가했습니다.
  4. 비주얼 스튜디오 2008

의 Web.config에 <webHttpBinding>에서 태그의 crossDomainScriptAccessEnabled 속성을 추가하는 방법에 대한 언급 대부분의 사람들. 나는 이것이 잘 작동하는지 아닌지를 잘 모르지만 3.5 버전에서는 사용 가능하지 않으므로 선택의 여지가 없다. 나는 또한 Web.config의에서 다음과 같은 태그를 추가는 ...

<httpProtocol> <customHeaders> <add name="Access-Control-Allow-Origin" value="*" /> <add name="Access-Control-Allow-Methods" value="GET" /> <add name="Access-Control-Allow-Headers" value="Content-Type, Accept" /> </customHeaders> </httpProtocol>

하지만 행운을 작동합니다 발견 ... 이러한 옵션으로 많은 어려움을 겪고 후 405 방법이 아니다 허용 오차

을 받고 유지 아래 주어진대로 동적으로 global.asax 파일에이 헤더를 추가하는 또 다른 해결책을 찾았습니다. ...

protected void Application_BeginRequest(object sender, EventArgs e) 
{ 
    HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "*"); 
    if (HttpContext.Current.Request.HttpMethod == "OPTIONS") 
    { 
     HttpContext.Current.Response.AddHeader("Cache-Control", "no-cache"); 
     HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "GET, POST"); 
     HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "Content-Type, Accept, Authorization"); 
     HttpContext.Current.Response.AddHeader("Access-Control-Max-Age", "1728000"); 
     HttpContext.Current.Response.End(); 
    } 
} 

그리고 web.config에서 제거하십시오. 웹 사이트를 게시하고 클라이언트 측 jquery/ajax를 계속하면 API 호출에서 데이터를 가져옵니다. 행운을 빕니다!

+0

가 작동하지 않는 경우 여전히 옵션에서 405를 얻습니다. –

2

하단의 CORS 재 작업에 몇 가지 문제 만 추가하려고합니다. 입력 문제가 GET 및 POST 방법을 지원하지 않으면 OPTIONS 요청이 실제로 허용 된 올바른 헤더를 반환하지 않는 문제가 있습니다. 실제로 어떤 메소드가 실제로 WCF 엔드 포인트에서 허용되는지는 알지 못합니다. 클라이언트가 OPTIONS 요청을 수행 할 때 응용 프로그램의 모든 단일 엔드 포인트에 대해 인위적으로 말하는 "GET, POST"가 허용됩니다. 지원됨).

OPTIONS 메소드의 정보를 사용하여 CORS 요청의 경우와 같이 올바른 메소드 목록을 반환하지 않는 것이 좋을 수도 있습니다. 그렇지만 필요한 경우 이 질문에 솔루션처럼 뭔가를 :

Webinvoke(Method="OPTIONS", UriTemplate="")

을하고 "적절한를 포함하여 응답에 적절한 헤더를로드하는 적절한 방법을 (전화 : 기본적으로 How to handle Ajax JQUERY POST request with WCF self-host

, 각 엔드 포인트 구현한다 액세스 제어 허용 - Meth od "목록)을 호출자에게 보냅니다. 호스트 된 WCF 끝 점이 자동으로 우리를 위해 수행하지 않는다는 점만 싫증이납니다. 그러나 이것은 끝점을보다 세밀하게 제어 할 수있는 해결 방법입니다. 는 해당 솔루션에 적절한 응답 헤더는 엔드 포인트 구현에로드됩니다

public void GetOptions() 
    { 
     // The data loaded in these headers should match whatever it is you support on the endpoint 
     // for your application. 
     // For Origin: The "*" should really be a list of valid cross site domains for better security 
     // For Methods: The list should be the list of support methods for the endpoint 
     // For Allowed Headers: The list should be the supported header for your application 

     WebOperationContext.Current.OutgoingResponse.Headers.Add("Access-Control-Allow-Origin", "*"); 
     WebOperationContext.Current.OutgoingResponse.Headers.Add("Access-Control-Allow-Methods", "POST, GET, OPTIONS"); 
     WebOperationContext.Current.OutgoingResponse.Headers.Add("Access-Control-Allow-Headers", "Content-Type, Accept, Authorization"); 
    } 
-2

시도 사용할 수 있습니다. 대신 WebInvoke(Method = "GET")

관련 문제