当启动webapi项目调用其中一个url时报该错误,解决方法如下:
之前是这么写的:
WebApiConfig.Register(GlobalConfiguration.Configuration);
改为:
GlobalConfiguration.Configure(WebApiConfig.Register);
问题就解决了。
服务端的webapi接口用fiddler,或swagger,postman调用都没问题,
服务端的方法如下:
[HttpPost]
[Route("getnews")]
public DtoResponse GetNews(DtoRequest call, int newsId)
{
var result = News.GetNewsById(newsId);
return result;
}
前端调用如下:
function GetDataTest( ) {
var req = {
"SessionId": "akjlmksdifklsdkkkosldiofkklkjsd",
"UsePool": true,
"ResponseSign": "sdfwedfvdsfe",
"AppId": 4,
"Ip": "127.0.0.1"
};
ajaxProcess("http://localhost:83/news/getnews?newsId=44901", req, function callSuccess(oRet) {
var result = oRet.Data;
if (result != null) {
} else {
}
}, function callError(e) {
//alert(e);
});
}
$.ajax({
url: url,
type: "POST",
timeout: waitSconds,
headers: { "Content-Type": "application/json" },
data: JSON.stringify(pdata),
success: function (result) {
if (successCallBack) {
if (result == null) {
if (errorCallBack) errorCallBack();
return;
}
if (result.err) {
if (errorCallBack) errorCallBack(result.err);
} else {
successCallBack(result);
if (okCallback) okCallback();
}
}
if (proccessObj) proccessObj.removeChild(a);
}, error: function (err) {
if (errorCallBack) errorCallBack(err);
if (proccessObj) proccessObj.removeChild(a);
if (errCallback) errCallback();
}
});
ajax调用里不加headers这个设置 headers: { "Content-Type": "application/json" }, 可以调用到该action,但call参数获取不到,加上headers则报如题的错误,解决方法分二步,
一是在web.config 加上如下设置,有些设置项不是针对解决此问题的,一并贴上:
二是在 global.asax.cs 里加上
protected void Application_BeginRequest()
{
if (Request.Headers.AllKeys.Contains("Origin") && Request.HttpMethod == "OPTIONS")
{
Response.End();
}
}
原因分析:后来注意到失败的请求Method是OPTIONS,奇怪了,明明是Post请求,怎么出现了Method为OPTIONS的请求呢?在Global.asax里加上如下处理:
protected void Application_BeginRequest()
{
if (Request.Headers.AllKeys.Contains("Origin") && Request.HttpMethod == "OPTIONS")
{
Response.End();
}
}
再试,成功了。但是看记录,会有两个请求,一个是OPTIONS请求返回200成功,一个是自己的PUT请求,返回200成功。那么这个OPTIONS请求到底是什么?百度了一下得到了答案:
Preflighted Requests(预检请求)
Preflighted Requests是CORS中一种透明服务器验证机制。预检请求首先需要向另外一个域名的资源发送一个 HTTP OPTIONS 请求头,其目的就是为了判断实际发送的请求是否是安全的。
下面的2种情况需要进行预检:
1、简单请求,比如使用Content-Type 为 application/xml 或 text/xml 的 POST 请求;
2、中设置自定义头,比如 X-JSON、X-MENGXIANHUI 等。
原来如此,在js发起PUT请求的时候,头部设置了XMLHttpRequest.setRequestHeader("Content-Type", "application/json"),所以请求的时候会多出一个OPTIONS,如果去掉这个头,就不会多出这次请求了。
参考来源: https://www.cnblogs.com/SilenceTom/p/6697484.html
这个地方也有个问题,如果注册了这个处理类 internal class RequestMessageHandler : DelegatingHandler
发现在Application_BeginRequest加了上面的处理后还是无效,发现请求还是流转到后续的处理过程中,在RequestMessageHandler的SendAsync再加上这个处理即可,如下:
if (request.Method.ToString().ToUpper() == "OPTIONS")
{
var response = new HttpResponseMessage(HttpStatusCode.OK);
return response;
}
在webapi中用了swagger来生成文档,但当某个方法的返回类型或方法用了泛型后就会报如题的错误,分析可能是swagger在解析泛型方法或返回值的时候不支持。
--- end ---