webapi 问题收集

1 请确保在所有其他初始化代码后面的应用程序启动代码中调用 HttpConfiguration.EnsureInitialized()

当启动webapi项目调用其中一个url时报该错误,解决方法如下:

之前是这么写的:
WebApiConfig.Register(GlobalConfiguration.Configuration);
改为:
GlobalConfiguration.Configure(WebApiConfig.Register);

问题就解决了。

2 Ajax调用webapi接口,报错:Response for preflight has invalid HTTP status code 405,method not allowed

服务端的webapi接口用fiddler,或swagger,postman调用都没问题,

服务端的方法如下:

[HttpPost]
[Route("getnews")]
public DtoResponse<DtoNewsSimple> 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 加上如下设置,有些设置项不是针对解决此问题的,一并贴上:

<system.webServer>
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Methods" value="GET, POST, OPTIONS, PUT, PATCH, DELETE" />
<add name="Access-Control-Allow-Headers" value="accept, authorization, Content-Type" />
<remove name="X-Powered-By" />
</customHeaders>
</httpProtocol></system.webServer>

二是在 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,如果去掉这个头,就不会多出这次请求了。
 

这个地方也有个问题,如果注册了这个处理类 internal class RequestMessageHandler : DelegatingHandler

发现在Application_BeginRequest加了上面的处理后还是无效,发现请求还是流转到后续的处理过程中,在RequestMessageHandler的SendAsync再加上这个处理即可,如下:

if (request.Method.ToString().ToUpper() == "OPTIONS")
{
var response = new HttpResponseMessage(HttpStatusCode.OK);
return response;
}

3 "Error":"DynamicMethod 的类型所有者无效

在webapi中用了swagger来生成文档,但当某个方法的返回类型或方法用了泛型后就会报如题的错误,分析可能是swagger在解析泛型方法或返回值的时候不支持。

 

--- end ---