AngularJS、REST、C# 服务、405 - 不允许发布方法

Posted

技术标签:

【中文标题】AngularJS、REST、C# 服务、405 - 不允许发布方法【英文标题】:AngularJS , REST, C# Service, 405 - Post Method Not Allowed 【发布时间】:2017-08-16 09:24:49 【问题描述】:

我正在尝试创建一个完整的 Angularjs 网站进行培训。我已经阅读了很多关于这个Method not allowed的文章,但没有找到解决方案。我正在尝试将数据对象发送到我的服务。

错误:加载资源失败:服务器响应状态为 405(不允许方法)

这是我的 AngularJS 部分。

var addNews =
        
            Title: newsList.newsTitle,
            NewsContent: newsList.newsContent,
            CreationDate: newsList.newsCreationDate,
            CreatedBy: newsList.newsAuthor,
            ModificationDate: newsList.newsCreationDate,
            ModifiedBy: newsList.newsAuthor
        ;

    var news = JSON.stringify(addNews);


    $http(
        method: 'POST',
        dataType: 'json',
        url: 'http://localhost:11672/InfinytecServices.svc/SaveNews',
        headers: 
            'Content-Type': 'application/json',
            'Accept': 'application/json'
        ,
        data: news
    );

这是我的服务部分

    [OperationContract]
    [WebInvoke(Method = "POST",
        UriTemplate = "/SaveNews",
        RequestFormat = WebMessageFormat.Json,
        ResponseFormat = WebMessageFormat.Json)]
    int SaveNews(News news);

WebConfig 即将上线

<?xml version="1.0" encoding="utf-8"?>
<configuration>

  <appSettings>
    <add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
  </appSettings>

  <system.web>
    <compilation debug="true" targetFramework="4.6.1" />
    <httpRuntime targetFramework="4.6.1"/>
  </system.web>

  <system.serviceModel>
    <protocolMapping>
      <add binding="webHttpBinding" scheme="http" />
    </protocolMapping>

    <extensions>
      <behaviorExtensions>
        <add
          name="crossOriginResourceSharingBehavior"
          type="InfinytecWebService.CORSEnablingBehavior, InfinytecWebService, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/>
      </behaviorExtensions>
    </extensions>

    <behaviors>
      <serviceBehaviors>
        <behavior name="serviceBehavior">
          <serviceMetadata httpGetEnabled="true" httpsGetEnabled="false"/>
          <serviceDebug includeExceptionDetailInFaults="true"/>
        </behavior>
      </serviceBehaviors>
      <endpointBehaviors>
        <behavior name="web">
          <webHttp/>
          <crossOriginResourceSharingBehavior />
        </behavior>
      </endpointBehaviors>
    </behaviors>

    <services>
      <service behaviorConfiguration="serviceBehavior" name="InfinytecWebService.InfinytecServices">
        <endpoint address=""
                  behaviorConfiguration="web"
                  binding="webHttpBinding"
                  contract="InfinytecWebService.IInfinytecServices" />
      </service>
    </services>

    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />

  </system.serviceModel>

  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>
    <directoryBrowse enabled="true"/>
  </system.webServer>

</configuration>

至少,CORS

public class CORSEnablingBehavior : BehaviorExtensionElement, IEndpointBehavior

    
        public void AddBindingParameters(
            ServiceEndpoint endpoint,
            BindingParameterCollection bindingParameters) 

        public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)  

        public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
        
            endpointDispatcher.DispatchRuntime.MessageInspectors.Add(
              new CORSHeaderInjectingMessageInspector()
            );
        

        public void Validate(ServiceEndpoint endpoint)  

        public override Type BehaviorType  get  return typeof(CORSEnablingBehavior);  

        protected override object CreateBehavior()  return new CORSEnablingBehavior(); 

        private class CORSHeaderInjectingMessageInspector : IDispatchMessageInspector
        
            public object AfterReceiveRequest(
              ref Message request,
              IClientChannel channel,
              InstanceContext instanceContext)
            
                return null;
            
            private static IDictionary<string, string> _headersToInject = new Dictionary<string, string>
          
             "Access-Control-Allow-Origin", "*" ,
             "Access-Control-Request-Method", "POST,GET,PUT,DELETE,OPTIONS" ,
             "Access-Control-Allow-Headers", "X-Requested-With,Content-Type" 
          ;
            public void BeforeSendReply(ref Message reply, object correlationState)
            
                var httpHeader = reply.Properties["httpResponse"] as HttpResponseMessageProperty;
                foreach (var item in _headersToInject)
                    httpHeader.Headers.Add(item.Key, item.Value);
            
        
    

你能帮帮我吗?

提前谢谢! :)

【问题讨论】:

您能否发布您的浏览器网络选项卡的屏幕截图。浏览器进行了两次调用,一次使用 OPTIONS,另一次使用 POST 方法。当您的服务使用 OPTIONS 方法接收请求时,它应该返回 CORS 信息并在请求到达您的 api 方法之前结束请求。由于 api 只接受 POST 它无法处理 OPTIONS 请求。 在帖子中添加,我还添加了控制台选项卡。谢谢 :) 【参考方案1】:

尝试以下方法之一

使用 Method="OPTIONS" 定义另一个 WebInvoke 方法,该方法应返回空内容,因为您的 CORS 行为处理程序添加了浏览器所需的所有预检头。 如果是 OPTIONS,您的 CORS 扩展应该分析当前请求 METHOD,它应该短路并返回带有飞行前标头的空内容。如果方法类型是“GET”/“POST”,它应该让请求通过以由端点处理。

浏览器发出两个请求,一个使用选项获取飞行前信息,另一个用于实际的 api 调用。

您遇到的问题是浏览器 Method=OPTIONS 的第一次调用被您的端点拒绝。因为它只能处理POST。

【讨论】:

以上是关于AngularJS、REST、C# 服务、405 - 不允许发布方法的主要内容,如果未能解决你的问题,请参考以下文章

从 AngularJS POST 到 Django API 以获取 JWT 并返回 405 错误

405 方法不允许使用 $http 服务 AngularJS

地理服务器返回 405:不允许的方法

WCF REST 服务为 POST 返回 405

加载资源失败:服务器从 Angularjs 响应状态为 405(不允许方法)到 WebApi

AngularJS:$http 服务 GET 到 php 服务器:请求方法:选项,状态代码:405 方法不允许