WCF RESTful 应用程序 PUT、POST、DELETE 收到相同的错误:“该方法不允许。”
Posted
技术标签:
【中文标题】WCF RESTful 应用程序 PUT、POST、DELETE 收到相同的错误:“该方法不允许。”【英文标题】:WCF restful application PUT, POST, DELETE receive the same error: "the method is not allowed." 【发布时间】:2020-06-29 15:56:10 【问题描述】:我创建了一个在 WCF 上使用 RESTFUL 架构实现的服务器。使用实体框架和 mysql DB 用 C# 编写。代码如下。 VS 不会产生任何错误,GET 方法工作正常,它从数据库输出数据。但是,所有其他方法(PUT、POST、DELETE、GetDetails)都会收到相同的错误:“不允许使用该方法。”也许你能说出我的错误是什么? 如果有几个错误,那我将不胜感激。我刚开始研究这个,所以我承认可能会有很多错误。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Web;
namespace WcfRestFullService
[DataContract]
public class CustomerDataContract
[DataMember]
public string Id_Cus get; set;
[DataMember]
public string FirstName_Cus get; set;
[DataMember]
public string LastName_Cus get; set;
[DataMember]
public string PhoneNum_Cus get; set;
[DataMember]
public string Email_Cus get; set;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
namespace WcfRestFullService
// NOTE: You can use the "Rename" command on the "Refactor" menu to change the interface name "ICustomerSevice" in both code and config file together.
[ServiceContract]
public interface ICustomerSevice
[OperationContract]
[WebInvoke(Method = "GET", RequestFormat = WebMessageFormat.Json,
ResponseFormat = WebMessageFormat.Json, UriTemplate = "/GetAllCustomer/")]//ok
List<CustomerDataContract> GetAllCustomer();
[OperationContract]
[WebGet(RequestFormat = WebMessageFormat.Json,
ResponseFormat = WebMessageFormat.Json,
UriTemplate = "/CustomerDetails/Id_Cus")]
CustomerDataContract CustomerDetails(String Id_Cus);
[OperationContract]
[WebInvoke(Method = "DELETE", ResponseFormat = WebMessageFormat.Json,
RequestFormat = WebMessageFormat.Json,
BodyStyle = WebMessageBodyStyle.Bare)]
void DeleteCustomer(String Id_Cus);
[OperationContract]
[WebInvoke(Method = "POST", ResponseFormat = WebMessageFormat.Json,
RequestFormat = WebMessageFormat.Json,
BodyStyle = WebMessageBodyStyle.Wrapped,
UriTemplate = "/InsertCustomer/")]//problem
void InsertCustomer(CustomerDataContract customerDataContract);
[OperationContract]
[WebInvoke(Method = "PUT",ResponseFormat = WebMessageFormat.Json,
RequestFormat = WebMessageFormat.Json,
BodyStyle = WebMessageBodyStyle.Bare,
UriTemplate = "/UpdateCustomer/")]//problem
void UpdateCustomer(CustomerDataContract customerDataContract);
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</configSections>
<appSettings>
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
</appSettings>
<system.web>
<compilation debug="true" targetFramework="4.8" />
<httpRuntime targetFramework="4.8" />
</system.web>
<system.serviceModel>
<services>
<service name="WcfRestFullService.CustomerSevice" behaviorConfiguration="serviceBehavior">
<endpoint address=""
binding="webHttpBinding"
contract="WcfRestFullService.ICustomerSevice"
behaviorConfiguration="web"></endpoint>
</service>
</services>
<!--<services>
<service name="WcfRestFullService.CustomerPreferences" behaviorConfiguration="serviceBehavior">
<endpoint address=""
binding="webHttpBinding"
contract="WcfRestFullService.ICustomerPreferences"
behaviorConfiguration="web"></endpoint>
</service>
</services>-->
<behaviors>
<endpointBehaviors>
<behavior name="web">
<webHttp />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="serviceBehavior">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
<behavior name="">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<protocolMapping>
<add binding="webHttpBinding" scheme="https" />
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true" />
<!--
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" />
</system.webServer>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.6.0" newVersion="4.0.6.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Memory" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.1.1" newVersion="4.0.1.1" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Extensions.Primitives" publicKeyToken="adb9793829ddae60" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.1.2.0" newVersion="3.1.2.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Extensions.Configuration.Abstractions" publicKeyToken="adb9793829ddae60" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.1.2.0" newVersion="3.1.2.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Extensions.DependencyInjection.Abstractions" publicKeyToken="adb9793829ddae60" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.1.2.0" newVersion="3.1.2.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Extensions.Caching.Abstractions" publicKeyToken="adb9793829ddae60" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.1.2.0" newVersion="3.1.2.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Extensions.Options" publicKeyToken="adb9793829ddae60" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.1.2.0" newVersion="3.1.2.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Extensions.Logging.Abstractions" publicKeyToken="adb9793829ddae60" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.1.2.0" newVersion="3.1.2.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Extensions.DependencyInjection" publicKeyToken="adb9793829ddae60" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.1.2.0" newVersion="3.1.2.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.ComponentModel.Annotations" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.2.1.0" newVersion="4.2.1.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="MySql.Data" publicKeyToken="c5687fc88969c44d" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-8.0.19.0" newVersion="8.0.19.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.EntityFrameworkCore" publicKeyToken="adb9793829ddae60" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.1.2.0" newVersion="3.1.2.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.EntityFrameworkCore.Abstractions" publicKeyToken="adb9793829ddae60" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.1.2.0" newVersion="3.1.2.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Extensions.Logging" publicKeyToken="adb9793829ddae60" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.1.2.0" newVersion="3.1.2.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Diagnostics.DiagnosticSource" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.5.0" newVersion="4.0.5.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Numerics.Vectors" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.1.4.0" newVersion="4.1.4.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Buffers" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.3.0" newVersion="4.0.3.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Threading.Tasks.Extensions" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.2.0.1" newVersion="4.2.0.1" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Google.Protobuf" publicKeyToken="a7d26565bac4d604" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.11.4.0" newVersion="3.11.4.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="BouncyCastle.Crypto" publicKeyToken="0e99375e54769942" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-1.8.5.0" newVersion="1.8.5.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.EntityFrameworkCore.Relational" publicKeyToken="adb9793829ddae60" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.1.2.0" newVersion="3.1.2.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
<entityFramework>
<providers>
<provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
<!--<provider invariantName="MySql.Data.MySqlClient" type="MySql.Data.MySqlClient.MySqlProviderServices, MySql.Data.Entity.EF6, Version=6.10.9.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d">
</provider>-->
<provider invariantName="MySql.Data.MySqlClient" type="MySql.Data.MySqlClient.MySqlProviderServices, MySql.Data.EntityFramework, Version=8.0.19.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d" />
</providers>
</entityFramework>
<connectionStrings>
<add name="MySQLEntities" connectionString="metadata=res://*/Model.Model.csdl|res://*/Model.Model.ssdl|res://*/Model.Model.msl;provider=MySql.Data.MySqlClient;provider connection string="server=localhost;user id=root;password=l10ksfnq5h2c;database=chik-chak"" providerName="System.Data.EntityClient" />
</connectionStrings>
</configuration>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using MySql.Data;
using System.Data.Entity;
using WcfRestFullService.Model;
namespace WcfRestFullService
// NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "CustomerSevice" in code, svc and config file together.
// NOTE: In order to launch WCF Test Client for testing this service, please select CustomerSevice.svc or CustomerSevice.svc.cs at the Solution Explorer and start debugging.
public class CustomerSevice : ICustomerSevice
MySQLEntities dc;
public CustomerSevice()
dc = new MySQLEntities();
public List<CustomerDataContract> GetAllCustomer()
var query = (from a in dc.customers
select a).Distinct();
List<CustomerDataContract> CustomersList = new List<CustomerDataContract>();
query.ToList().ForEach(x =>
CustomersList.Add(new CustomerDataContract
Id_Cus = Convert.ToString(x.Id_Cus),
FirstName_Cus = x.FirstName_Cus,
LastName_Cus = x.LastName_Cus,
PhoneNum_Cus = x.PhoneNum_Cus.ToString(),
Email_Cus = x.Email_Cus,
);
);
return CustomersList;
public CustomerDataContract CustomerDetails(string Id_Cus)
CustomerDataContract Cust = new CustomerDataContract();
try
var query = (from a in dc.customers
where a.Id_Cus.Equals(Id_Cus)
select a).Distinct().FirstOrDefault();
Cust.Id_Cus = query.Id_Cus.ToString();
Cust.FirstName_Cus = query.FirstName_Cus;
Cust.LastName_Cus = query.LastName_Cus;
Cust.PhoneNum_Cus = query.PhoneNum_Cus.ToString();
Cust.Email_Cus = query.Email_Cus;
catch (Exception ex)
throw new FaultException<string>(ex.Message);
return Cust;
// DELETE
public void DeleteCustomer(string Id_Cus)
MySQLEntities Cust = new MySQLEntities(); //check the file Model.edmx->ModelContext.tt->MySQLEntitys
int k = Convert.ToInt32(Id_Cus);
customer cur = (from n in dc.customers
where n.Id_Cus == k
select n).First();
Cust.customers.Remove(cur);
Cust.SaveChanges();
//Insert/POST
public void InsertCustomer(CustomerDataContract customerDataContract)
MySQLEntities Cust = new MySQLEntities();
customer cust = new customer();
cust.Id_Cus = Convert.ToInt32(customerDataContract.Id_Cus);
cust.FirstName_Cus = customerDataContract.FirstName_Cus;
cust.LastName_Cus = customerDataContract.LastName_Cus;
cust.PhoneNum_Cus = Convert.ToInt32(customerDataContract.PhoneNum_Cus);
cust.Email_Cus = customerDataContract.Email_Cus;
Cust.customers.Add(cust);
Cust.SaveChanges();
//Update/PUT
public void UpdateCustomer(CustomerDataContract customerDataContract)
//using (CustomerDataContract Cust = new CustomerDataContract())
using (MySQLEntities Cust = new MySQLEntities())
customer cust = Cust.customers.Where(n => n.Id_Cus == (Convert.ToInt32(customerDataContract.Id_Cus))).First();
cust.Id_Cus =Convert.ToInt32(customerDataContract.Id_Cus);
cust.FirstName_Cus = customerDataContract.FirstName_Cus;
cust.LastName_Cus = customerDataContract.LastName_Cus;
cust.PhoneNum_Cus =Convert.ToInt32(customerDataContract.PhoneNum_Cus);
cust.Email_Cus = customerDataContract.Email_Cus;
Cust.SaveChanges();
namespace WcfRestFullService.Model
using System;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
public partial class MySQLEntities : DbContext
public MySQLEntities()
: base("name=MySQLEntities")
protected override void OnModelCreating(DbModelBuilder modelBuilder)
throw new UnintentionalCodeFirstException();
public virtual DbSet<customer> customers get; set;
public virtual DbSet<customerpreference> customerpreferences get; set;
public virtual DbSet<dish> dishes get; set;
public virtual DbSet<dishesranking> dishesrankings get; set;
public virtual DbSet<ingridient> ingridients get; set;
public virtual DbSet<order> orders get; set;
public virtual DbSet<restaraunt> restaraunts get; set;
public virtual DbSet<type_dishes> type_dishes get; set;
public object Parameters get; internal set;
enter image description here
enter image description here
enter image description here
enter image description here
enter image description here
【问题讨论】:
WCF 不是最好的工具。 【参考方案1】:你应该知道浏览器发送的默认请求使用Get
HTTP动词,而操作合约需要DELETE
HTTP动词。
按 F12,网络查看请求的详细信息。
测试POST/DELETE/PUT
请求的正确方法是使用PostMan
软件(或其他一些工具,例如Fiddler
)发送请求。
函数的定义。
[OperationContract]
[WebInvoke(Method ="DELETE",RequestFormat =WebMessageFormat.Json,ResponseFormat =WebMessageFormat.Json)]
string GetResult(string id);
Fiddler 中的请求。 如果参数是复合类型,要注意请求的数据格式。 详情见以下链接。How to call RestFul WCF POST service With Custom Object using POSTMAN or any client tool application? 如果有什么我可以帮忙的,请随时告诉我。
【讨论】:
我尝试过 Fiddler,但在 PUT 和 POST 方法中出现错误(307 和 405 错误)。并且在 DELETE 方法中“System.InvalidOperationException: '无法删除该对象,因为它在 ObjectStateManager 中找不到。” " 和 VS 中的错误:Cust.customers.Remove(cur); 它可能是什么?感谢您的最后回答:) 这是因为在数据库中没有找到要删除的对象。 customer cur = (from n in dc.customers where n.Id_Cus == k select n).First();唯一的参数应该由正文部分而不是 URL 中的查询字符串传递,因为您使用删除动词。就像上面的截图一样。 此外,您应该注意数据格式。我还没有看到customdatacontract
的定义。 ***.com/questions/58495488/…
非常感谢您的回复!是的,确实,我错误地附加了“custompreferencescontract”而不是“customdatacontract”,现在我已经编辑了所有内容并正确添加了它。我尝试按照您的建议进行操作,但在所有变体中:“localhost: 51265 / CustomerSevice.svc/GetAllCustomer /”甚至“http://localhost:51265 / CustomerSevice.svc / DeleteCustomer /”。我根据截图做所有事情。如果这对你来说没什么大不了的,也许我会在某个信使中给你发一张截图?我只是不明白我做错了什么。再次感谢您的回答。
移除 UriTemplate 并添加内容类型:Application/json。我已经在回复中添加了方法的定义。以上是关于WCF RESTful 应用程序 PUT、POST、DELETE 收到相同的错误:“该方法不允许。”的主要内容,如果未能解决你的问题,请参考以下文章
应用程序/json内容类型请求的Restful WCF POST问题
在 MVC 5 中调用 WCF Restful POST 方法