我有一个Web Api控制器.它表现得很奇怪.当我使用PostMan时,我可以在Web Api上访问POST方法,但是当我从.net使用HttpWebRequest时,它返回(405)Method Not Allowed.
我把Web Api代码放在这里:
我把Web Api代码放在这里:
using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Net.Http; using System.Web; using System.Web.Http; namespace MyProject.Controllers { public class TestController : ApiController { [HttpPost] public int buy(OrderResult value) { try { if (value.InvoiceDate != null && value.Result == 1) { return 0; } } catch{} return -1; } } public class OrderResult { public int Result { get; set; } public long InvoiceNumber { get; set; } public string InvoiceDate { get; set; } public long TimeStamp { get; set; } } }
这是我的WebApiConfig.cs:
using System; using System.Collections.Generic; using System.Linq; using System.Web.Http; namespace MyProject { public static class WebApiConfig { public static void Register(HttpConfiguration config) { config.Routes.MapHttpRoute( name: "DefaultApi",routeTemplate: "api/{controller}/{action}/{id}",defaults: new { action = RouteParameter.Optional,id = RouteParameter.Optional } ); } } }
这是我从另一个.NET项目发送POST请求的方式:
using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net; using System.Text; using System.Web; namespace MyProject.Controllers { public static class WebReq { public static string PostRequest(string Url,string postParameters) { try { HttpWebRequest myReq = (HttpWebRequest)WebRequest.Create(Url); myReq.Method = "POST"; myReq.Timeout = 30000; myReq.Proxy = null; byte[] postData = Encoding.UTF8.GetBytes(postParameters); myReq.ContentLength = postData.Length; myReq.ContentType = "application/x-www-form-urlencoded"; using (Stream requestWrite = myReq.GetRequestStream()) { requestWrite.Write(postData,postData.Length); requestWrite.Close(); using (HttpWebResponse webResponse = (HttpWebResponse)myReq.GetResponse()) { if (webResponse.StatusCode == HttpStatusCode.OK) { using (Stream str = webResponse.GetResponseStream()) { using (StreamReader sr = new StreamReader(str)) { return sr.ReadToEnd(); } } } return null; } } } catch (Exception e) { var message = e.Message; return null; } } } }
<modules runAllManagedModulesForAllRequests="true"> <remove name="WebDAVModule" /> </modules>
这很奇怪,因为我可以从PostMan成功发送POST请求. PostMan将此代码发送到API.
POST /api/Test/buy HTTP/1.1 Host: domain.com Cache-Control: no-cache Postman-Token: 9220a4e6-e707-5c5f-ea61-55171a5dd95f Content-Type: application/x-www-form-urlencoded InvoiceDate=28012016&Result=1
我将不胜感激任何解决问题的建议.
解决方法
byte[] postData = Encoding.UTF8.GetBytes(postParameters); myReq.ContentLength = postData.Length; myReq.ContentType = "application/x-www-form-urlencoded"; using (Stream requestWrite = myReq.GetRequestStream()) { requestWrite.Write(postData,postData.Length);
您很可能不会发送正确的x-www-form-urlencoded请求.您可能无法正确编码从postParameters传入的数据.见Post form data using HttpWebRequest
由于您未根据x-www-form-urlencoded生成有效的OrderResult对象,因此路由选择器不会选择您的Buy操作.这就是你不允许POST的原因.
如果您更改了OrderResult value = null,则可能会进入控制器,因为它现在是可选参数.然而,这不是你想要的,除非你有一个奇怪的控制器,行为如下:
Buy(OrderResult value = null) { if(value== null) value = MyCustomDeserializeFromRequestBody(RequestContext) ... }
最后你真的不应该使用这个类,现代开发有更好的结构https://stackoverflow.com/a/31147762/37055 https://github.com/hhariri/EasyHttp我的头顶