【问题标题】:AngularJS , REST, C# Service, 405 - Post Method Not AllowedAngularJS、REST、C# 服务、405 - 不允许发布方法
【发布时间】: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 请求。
  • 在帖子中添加,我还添加了控制台选项卡。谢谢 :)

标签: c# angularjs rest http-status-code-405


【解决方案1】:

尝试以下方法之一

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

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

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

【讨论】:

    猜你喜欢
    • 2015-08-25
    • 2017-11-18
    • 2017-12-03
    • 2016-09-23
    • 2016-12-03
    • 2016-05-15
    • 1970-01-01
    • 2021-07-28
    • 1970-01-01
    相关资源
    最近更新 更多