WCF POST 方法返回“方法不允许”
Posted
技术标签:
【中文标题】WCF POST 方法返回“方法不允许”【英文标题】:WCF POST Method returning "Method not allowed" 【发布时间】:2018-07-21 17:55:51 【问题描述】:我有以下 WCF 网络服务:
我在IService1中定义
[OperationContract]
[WebInvoke(Method = "POST")]
string testSer();
在 Service1.svc 中
public string testSer()
return "test";
我正在从 C# winForm 应用程序调用 Web 服务,如下所示:
var client = new RestClient("http://localhost/webservices/Service1.svc/");
var request = new RestRequest("testSer", Method.POST);
IRestResponse response = client.Execute(request);
var content = response.Content; // raw content as string
MessageBox.Show(content);
返回的响应是“方法不允许”。如果我将方法类型更改为“GET”,它就可以工作。
如果我尝试从浏览器调用“POST”方法,返回的响应是“方法不允许”
我的配置文件:
<?xml version="1.0"?>
<configuration>
<connectionStrings>
<remove name="LocalSqlServer" />
<add name="LocalSqlServer" connectionString="Data Source=myserver;Initial Catalog=db;User ID=sa;Password=111;" />
</connectionStrings>
<appSettings>
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true"/>
</appSettings>
<system.web>
<compilation debug="true" targetFramework="4.5"/>
<httpRuntime targetFramework="4.5"/>
<httpModules>
<add name="ApplicationInsightsWebTracking" type="Microsoft.ApplicationInsights.Web.ApplicationInsightsHttpModule, Microsoft.AI.Web"/>
</httpModules>
</system.web>
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="false" multipleSiteBindingsEnabled="true" />
<services>
<service name="WcfService3.Service1">
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<endpoint address="" behaviorConfiguration="restfulBehavior" binding="webHttpBinding"
bindingConfiguration="jsonp" name="jsonService" contract="WcfService3.IService1" />
<endpoint address="soap" binding="basicHttpBinding" name="soapService" contract="WcfService3.IService1" />
</service>
</services>
<bindings>
<basicHttpBinding>
<binding name="soapService" />
</basicHttpBinding>
<webHttpBinding>
<binding name="jsonp" crossDomainScriptAccessEnabled="true" />
</webHttpBinding>
</bindings>
<behaviors>
<endpointBehaviors>
<behavior name="restfulBehavior">
<webHttp defaultOutgoingResponseFormat="Json" defaultBodyStyle="Wrapped" automaticFormatSelectionEnabled="False" />
<!--<enableWebScript />-->
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" policyVersion="Policy15" />/>
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<protocolMapping>
<add binding="basicHttpsBinding" scheme="https" />
</protocolMapping>
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true">
<remove name="ApplicationInsightsWebTracking"/>
<add name="ApplicationInsightsWebTracking" type="Microsoft.ApplicationInsights.Web.ApplicationInsightsHttpModule, Microsoft.AI.Web"
preCondition="managedHandler"/>
</modules>
<!--
To browse web app root directory during debugging, set the value below to true.
Set to false before deployment to avoid disclosing web app folder information.
-->
<directoryBrowse enabled="true"/>
<validation validateIntegratedModeConfiguration="false"/>
<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>
</system.webServer>
</configuration>
编辑 当我尝试使用 WCF 测试客户端(Microsoft Visual Studio 附带)测试服务时,我收到以下错误:
错误:无法从https://www.example.net/cms/Service1.svc/TestSer 获取元数据如果这是您有权访问的 Windows (R) Communication Foundation 服务,请检查您是否已在指定地址启用元数据发布。有关启用元数据发布的帮助,请参阅位于 http://go.microsoft.com/fwlink/?LinkId=65455.WS-Metadata Exchange 错误 URI:https://www.example.net/cms/Service1.svc/TestSer 元数据包含无法解析的引用的 MSDN 文档:“https://www.example.net/cms/Service1.svc/TestSer”。内容类型application/json;响应消息的 charset=utf-8 与绑定的内容类型不匹配(application/soap+xml;charset=utf-8)。如果使用自定义编码器,请确保正确实现 IsContentTypeSupported 方法。响应的前 34 个字节是:'"testSerResult":"test-1 service"'。HTTP GET 错误 URI:https://www.example.net/cms/Service1.svc/TestSer 下载 'https://www.example.net/cms/Service1.svc/TestSer' 时出错。请求失败,HTTP 状态为 405: Method Not Allowed。
【问题讨论】:
由于您只是返回一个带有当前 OperationContract 的字符串,因此您宁愿发出 GET 请求而不是 POST 请求。 是的,但是,如果我需要发送一个 JSON 字符串(大约 500 个字符或更多)并返回一个 JSON 字符串,GET 是否适用? 这实际上取决于您如何处理正在发送的数据。如果数据被处理或/和持久化(保存到数据库中),您应该使用 POST。如果数据仅用于查询和获取数据,那么您可以使用 GET。 如果我将操作合同更改为 [OperationContract] [WebInvoke(Method = "*")] 需要保存在数据库中,它可以工作,但是 * 是什么意思? 表示具体操作是允许所有HTTP请求方法(GET、POST、DELETE;OPTIONS ....) 【参考方案1】:像下面的代码一样更改webconfig
<system.webServer>
<handlers>
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<remove name="OPTIONSVerbHandler" />
<remove name="TRACEVerbHandler" />
<remove name="WebDAV" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
<modules>
<remove name="WebDAVModule" />
</modules>
<security>
<requestFiltering>
<verbs allowUnlisted="false">
<add verb="GET" allowed="true" />
<add verb="POST" allowed="true" />
<add verb="DELETE" allowed="true" />
<add verb="PUT" allowed="true" />
</verbs>
</requestFiltering>
</security>
</system.webServer>
【讨论】:
服务器现在返回:已检测到不适用于集成托管管道模式的 ASP.NET 设置。请注意,我正在从 winForm App 调用 Web 服务【参考方案2】:用
装饰您的运营合同[OperationContract]
[WebInvoke(Method = "POST")]
在你的 Web Config 中应该是这样的:
<system.serviceModel>
<client />
<behaviors>
<endpointBehaviors>
<behavior name="restfulBehavior">
<webHttp defaultOutgoingResponseFormat="Json" defaultBodyStyle="Wrapped" automaticFormatSelectionEnabled="False" />
<!--<enableWebScript />-->
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<basicHttpBinding>
<binding name="soapService" />
</basicHttpBinding>
<webHttpBinding>
<binding name="jsonp" crossDomainScriptAccessEnabled="true" />
</webHttpBinding>
</bindings>
<protocolMapping>
<add binding="basicHttpsBinding" scheme="https" />
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="false" multipleSiteBindingsEnabled="true" />
<services>
<service name="WcfService3.Service1">
<endpoint address="" behaviorConfiguration="restfulBehavior" binding="webHttpBinding" bindingConfiguration="jsonp" name="jsonService" contract="WcfService3.IService1" />
<endpoint address="mex" binding="mexHttpBinding" name="metadata" contract="IMetadataExchange" />
</service>
</services>
</system.serviceModel>
这是您从 post 端点返回的数据:
【讨论】:
@HassanShouman 没用?您确定您使用 webinvoke 装饰了操作合同并检查了配置吗?我复制了相同的环境、相同的服务及其工作。 你好没有没有工作!是的,我装饰了操作合同。我在问题中发布了我的配置文件 @HassanShouman 我在您的代码中找不到任何问题。我认为您正在尝试从浏览器访问 POST 方法。无法从浏览器访问 POST 方法端点,因为 POST 方法有一个 GET 方法不需要也没有的主体。 @HassanShouman 你看到我上次更新你的代码了吗? 让我们continue this discussion in chat.【参考方案3】:首先感谢大家,尤其感谢@jalison-evora 的帮助。
错误是由于 nginx 配置造成的。
请检查此链接
WCF Service Method Not Allowed When Using WebsiteName
【讨论】:
以上是关于WCF POST 方法返回“方法不允许”的主要内容,如果未能解决你的问题,请参考以下文章
WCF REST 服务返回 405:jQuery AJAX GET 不允许的方法
wcf REST 服务和 JQuery Ajax Post:方法不允许
自托管 WCF REST 服务 JSON POST 方法不允许