讓asp.net web api同時支持[AcceptVerbs("GET","POST")]


   在使用第三方接口時,有時候會看到接口同時支持GET和POST,當時想想webapi有AcceptVerbs特性,沒有細想便想當然肯定會支持,后來項目中需要用到,當時在沒有參數傳入下確實支持,直到早幾天,碰到需要傳入參數的接口.

   還是按照原來的思路去做,當寫參數時時用FromUri還是FromBody,這時問題來了,默認webapi是不能同時支持GET和POST時[當需接受多個參數時]。想了想web api與asp.net mvc接受參數綁定是不同的。

 
        

    經過一些搜索有了一些啟發,找到了如下面的代碼。

public class FromUriOrBodyParameterBinding : HttpParameterBinding
    {
        HttpParameterBinding _defaultUriBinding;
        HttpParameterBinding _defaultFormatterBinding;

        public FromUriOrBodyParameterBinding(HttpParameterDescriptor desc)
            : base(desc)
        {
            _defaultUriBinding = new FromUriAttribute().GetBinding(desc);
            _defaultFormatterBinding = new FromBodyAttribute().GetBinding(desc);
        }

        public override Task ExecuteBindingAsync(ModelMetadataProvider metadataProvider, HttpActionContext actionContext, CancellationToken cancellationToken)
        {
            if (actionContext.Request.Content != null && actionContext.Request.Content.Headers.ContentLength > 0)
            {
                return _defaultFormatterBinding.ExecuteBindingAsync(metadataProvider, actionContext, cancellationToken);
            }
            else
            {
                return _defaultUriBinding.ExecuteBindingAsync(metadataProvider, actionContext, cancellationToken);
            }
        }

  

config.ParameterBindingRules.Insert(0, x =>
            {
                if (x.ParameterType == typeof(LoginModel))
                {
                    return new FromUriOrBodyParameterBinding(x);
                }
                return null;
            });

 

到了此處,原理上是支持了。

但是作為程序員肯定對於這種寫法是不能容忍的.

后面想到FromBody特性。於是乎查看webapi源代碼。

翻閱源碼按照FromBody實現的思路,有了下面的代碼。  

 

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Parameter, Inherited = true, AllowMultiple = false)]
    public sealed class FromUriOrBodyAttribute : ParameterBindingAttribute
    {
        public override HttpParameterBinding GetBinding(HttpParameterDescriptor parameter)
        {
            return new FromUriOrBodyParameterBinding(parameter);
        }

        public class FromUriOrBodyParameterBinding : HttpParameterBinding
        {
            HttpParameterBinding _defaultUriBinding;
            HttpParameterBinding _defaultFormatterBinding;

            public FromUriOrBodyParameterBinding(HttpParameterDescriptor desc)
                : base(desc)
            {
                _defaultUriBinding = new FromUriAttribute().GetBinding(desc);
                _defaultFormatterBinding = new FromBodyAttribute().GetBinding(desc);
            }

            public override Task ExecuteBindingAsync(ModelMetadataProvider metadataProvider, HttpActionContext actionContext, CancellationToken cancellationToken)
            {
                if (actionContext.Request.Content != null && actionContext.Request.Content.Headers.ContentLength > 0)
                {
                    return _defaultFormatterBinding.ExecuteBindingAsync(metadataProvider, actionContext, cancellationToken);
                }
                else
                {
                    return _defaultUriBinding.ExecuteBindingAsync(metadataProvider, actionContext, cancellationToken);
                }
            }

        }
    }

  最終用法如下:

[AcceptVerbs("GET","POST")]
        public IHttpActionResult Login([FromUriOrBody]LoginModel login)
        {
            return Ok(login);
        }

  

 此處只當記錄一下解決問題的標記。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM