webapi 问题收集

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

参考来源: 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;
            }

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

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

--- end ---

猜你喜欢

转载自blog.csdn.net/huwei2003/article/details/80313438