webapi 过滤器获取body_webapi获取string body - CSDN
精华内容
参与话题
  • c# .net mvc webapi Filters 筛选获取 请求参数和响应内容

    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using System.Text;
    using Grass.Extend;
    
    namespace Grass.Mvc.Infrastructure.Filter
    {
        public class WebApiActionDebugFilter : System.Web.Http.Filters.ActionFilterAttribute
        {
            /// <summary>
            /// 是否开启调试
            /// </summary>
            private bool _isDebugLog = true;
    
            public string DebugId
            {
                set
                {
                    var session = System.Web.HttpContext.Current.Session;
                    if (session != null)
                    {
                        session["RequestDebugId"] = value;
                    }
                }
                get
                {
                    var session = System.Web.HttpContext.Current.Session;
                    if (session != null && session["RequestDebugId"]!=null)
                    {
                        return session["RequestDebugId"].ToString();
                    }
                    return string.Empty;
                }
            }
    
            public override void OnActionExecuting(System.Web.Http.Controllers.HttpActionContext context)
            {
                base.OnActionExecuting(context);
                //记录请求内容
                if (_isDebugLog)
                {
                    try
                    {
                        var guid = System.Guid.NewGuid().ToString();
                        DebugId = guid;
                        var session = System.Web.HttpContext.Current.Session;
                        var request = System.Web.HttpContext.Current.Request;
                        var keys = request.Form.AllKeys;
                        
                        var task = context.Request.Content.ReadAsStreamAsync();
                        var content = string.Empty;
                        using (System.IO.Stream sm = task.Result)
                        {
                            if (sm != null)
                            {
                                sm.Seek(0, SeekOrigin.Begin);
                                int len = (int) sm.Length;
                                byte[] inputByts = new byte[len];
                                sm.Read(inputByts, 0, len);
                                sm.Close();
                                content = Encoding.UTF8.GetString(inputByts);
                            }
                        }
                        string pars = string.Format("请求:\r\n id = {3};\r\n sessionId = {0};\r\n url = {1};\r\n contentType = {4};\r\n content = {2};"
                            ,""// (session==null)?"...":session.SessionID
                            , request.RawUrl
                            , content
                            , guid
                            , request.ContentType);
    
                    }
                    catch (Exception ex)
                    {
                    }
                }
            }
            public override void OnActionExecuted(System.Web.Http.Filters.HttpActionExecutedContext context)
            {
                base.OnActionExecuted(context);
                //记录请求内容
                if (_isDebugLog)
                {
                    try
                    {
                        var session = System.Web.HttpContext.Current.Session;
                        var task = context.Response.Content.ReadAsStringAsync();
                        var txt = task.Result;
                        string pars = string.Format("响应:\r\n id = {2};\r\n sessionId = {0};\r\n response = {1}"
                            , ""//(session == null) ? "..." : session.SessionID
                            , txt
                            , DebugId);
                    }
                    catch (Exception ex)
                    {
                    }
                }
            }
            
        }
    }


    展开全文
  • SpringBoot拦截器获取Request的body数据

    千次阅读 2019-02-20 15:20:06
    一、分析问题 由于拦截器中,request中getReader()和...重写HttpServletRequestWrapper把request保存下来,然后通过过滤器把保存下来的request再填充进去 1、写一个类,继承HttpServletRequestWrapper package c...

    一、分析问题

    由于拦截器中,request中getReader()和getInputStream()只能调用一次,到controller里数据就为空了。

    二、解决方法

    重写HttpServletRequestWrapper把request保存下来,然后通过过滤器把保存下来的request再填充进去

    1、写一个类,继承HttpServletRequestWrapper

    package com.jkinvest.restApi.config.interceptor;
    
    import javax.servlet.ReadListener;
    import javax.servlet.ServletInputStream;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletRequestWrapper;
    import java.io.*;
    
    public class RequestWrapper extends HttpServletRequestWrapper {
        private final String body;
    
        public RequestWrapper(HttpServletRequest request) {
            super(request);
            StringBuilder stringBuilder = new StringBuilder();
            BufferedReader bufferedReader = null;
            InputStream inputStream = null;
            try {
                inputStream = request.getInputStream();
                if (inputStream != null) {
                    bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
                    char[] charBuffer = new char[128];
                    int bytesRead = -1;
                    while ((bytesRead = bufferedReader.read(charBuffer)) > 0) {
                        stringBuilder.append(charBuffer, 0, bytesRead);
                    }
                } else {
                    stringBuilder.append("");
                }
            } catch (IOException ex) {
    
            } finally {
                if (inputStream != null) {
                    try {
                        inputStream.close();
                    }
                    catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                if (bufferedReader != null) {
                    try {
                        bufferedReader.close();
                    }
                    catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
            body = stringBuilder.toString();
        }
    
        @Override
        public ServletInputStream getInputStream() throws IOException {
            final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(body.getBytes());
            ServletInputStream servletInputStream = new ServletInputStream() {
                @Override
                public boolean isFinished() {
                    return false;
                }
                @Override
                public boolean isReady() {
                    return false;
                }
                @Override
                public void setReadListener(ReadListener readListener) {
                }
                @Override
                public int read() throws IOException {
                    return byteArrayInputStream.read();
                }
            };
            return servletInputStream;
    
        }
    
        @Override
        public BufferedReader getReader() throws IOException {
            return new BufferedReader(new InputStreamReader(this.getInputStream()));
        }
    
        public String getBody() {
            return this.body;
        }
    
    }

    2、拦截器取值修改

    RequestWrapper requestWrapper = new RequestWrapper(request);
                String jsonBody = requestWrapper.getBody();

    3、过滤器Filter,用来把request传递下去

    package com.jkinvest.restApi.config.interceptor;
    
    
    
    import javax.servlet.*;
    import javax.servlet.annotation.WebFilter;
    import javax.servlet.http.HttpServletRequest;
    import java.io.IOException;
    
    public class RepeatedlyReadFilter implements Filter {
    
        @Override
        public void init(FilterConfig filterConfig) throws ServletException {
    
        }
     
        @Override
        public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
            ServletRequest requestWrapper = null;
            if(servletRequest instanceof HttpServletRequest) {
                requestWrapper = new RequestWrapper((HttpServletRequest) servletRequest);
            }
            if(requestWrapper == null) {
                filterChain.doFilter(servletRequest, servletResponse);
            } else {
                filterChain.doFilter(requestWrapper, servletResponse);
            }
        }
     
        @Override
        public void destroy() {
    
        }
    }

    4、配置类修改

    /*
     * The MIT License (MIT)
     *
     * Copyright (c) 2014-2016 abel533@gmail.com
     *
     * Permission is hereby granted, free of charge, to any person obtaining a copy
     * of this software and associated documentation files (the "Software"), to deal
     * in the Software without restriction, including without limitation the rights
     * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     * copies of the Software, and to permit persons to whom the Software is
     * furnished to do so, subject to the following conditions:
     *
     * The above copyright notice and this permission notice shall be included in
     * all copies or substantial portions of the Software.
     *
     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
     * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
     * THE SOFTWARE.
     */
    
    package com.jkinvest.restApi.config;
    
    import com.jkinvest.restApi.config.interceptor.LoginInterceptor;
    import com.jkinvest.restApi.config.interceptor.RepeatedlyReadFilter;
    import org.springframework.boot.web.servlet.FilterRegistrationBean;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
    import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
    import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
    
    
    /**
     * @author cuiP
     */
    @Configuration
    public class WebMvcConfig extends WebMvcConfigurerAdapter {
    
        @Bean
        //这个为了解决拦截器不能注入问题
        public LoginInterceptor getLoginInterceptor(){
            return new LoginInterceptor();
        }
        @Bean
        public FilterRegistrationBean repeatedlyReadFilter() {
            FilterRegistrationBean registration = new FilterRegistrationBean();
            RepeatedlyReadFilter repeatedlyReadFilter = new RepeatedlyReadFilter();
            registration.setFilter(repeatedlyReadFilter);
            registration.addUrlPatterns("/*");
            return registration;
        }
    
    
        /**
         * 添加静态资源
         * @param registry
         */
        @Override
        public void addResourceHandlers(ResourceHandlerRegistry registry) {
            registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/");
        }
    
        /**
         * 添加拦截器
         * @param registry
         */
        @Override
        public void addInterceptors(InterceptorRegistry registry) {
            // 多个拦截器组成一个拦截器链
            // addPathPatterns 用于添加拦截规则
            // excludePathPatterns 用户排除拦截
            registry.addInterceptor(getLoginInterceptor()).addPathPatterns("/api/**")
                    .excludePathPatterns("/api/account/sendLoginSMS")
                    .excludePathPatterns("/api/account/login")
                    .excludePathPatterns("/api/index/**")
                    .excludePathPatterns("/api/public/**");
            super.addInterceptors(registry);
        }
    }
    

     

    展开全文
  • 前端传一个json对象,后端用字典接收 byte[] data = new byte[HttpContext.Current.Request.InputStream.Length]; HttpContext.Current.Request.InputStream.Read(data, 0, data.Length); string txt = ...

     前端传一个json对象,后端用字典接收

    byte[] data = new byte[HttpContext.Current.Request.InputStream.Length];
                HttpContext.Current.Request.InputStream.Read(data, 0, data.Length);
                string txt = System.Text.Encoding.UTF8.GetString(data);
                MemoryStream ms = null;
                try
                {
                    Dictionary<string, object> dictionary = null;
                    dictionary = Newtonsoft.Json.JsonConvert.DeserializeObject<Dictionary<string, object>>(txt);
                    var imageStr = dictionary["imageStr"].ToString();
                    var userRefid = dictionary["userRefid"].ToString();

     

     

    问题描述:

    1、网站向WebApi(以下简称Api) Post数据;

    2、Api的过滤器先处理验证,通过HttpContext.Current.Request.InputStream获取网站Post过来的流数据;

    3、问题出现了,如果我网站Post一个字节小于1000(大概是这个数目)的数据都没问题,如果我Post一个字节大于1000的就有问题了。当大于1000的时候,Api中获取的InputStream数据为空,但是如果去掉过滤器验证,直接跳到Api的控制器,这时Api的控制器就能获取到数据。详情见下图。

     

    这是成功的Post请求:

    这时,如果我再添加一点Post的数据量,问题就出现了,见下图:

    只要StreamReader读过1次,stream.Position的值就不为0。

    因此在StreamReader读取之前,加上stream.Position = 0

    展开全文
  • .net core3.0中多次读取body流方法中 启动倒带方式由Request.EnableRewind()变为了 request.EnableBuffering();...新建WebApi项目,测试过滤器代码如下: public class TestFilter : ActionFilterAttribute...

    .net core3.0中启动倒带方式由Request.EnableRewind()变为了 request.EnableBuffering(); 但是今天在过滤器中使用此方法时出现异常。原代码已经修改,下面以新建的项目做示例记录一下问题。新建WebApi项目,测试过滤器代码如下:

       public class TestFilter : ActionFilterAttribute
        {
            public override void OnActionExecuting(ActionExecutingContext context)
            {
                base.OnActionExecuting(context);
                var request = context.HttpContext.Request;
                //启动倒带方式
                request.EnableBuffering();
                if (request.Method.ToLower().Equals("post"))
                {
                	request.Body.Seek(0, SeekOrigin.Begin);
                    using (var reader = new StreamReader(request.Body, Encoding.UTF8))
                    {
                        var param = reader.ReadToEnd();
                    }
                    request.Body.Seek(0, SeekOrigin.Begin);
                }
              
            }
            public override void OnActionExecuted(ActionExecutedContext context)
            {
                base.OnActionExecuted(context);
            }
    
        }
    

    启动项目站点,发送post请求

    curl -X POST "http://localhost:5000/WeatherForecast" -H "accept: text/plain" -H "Content-Type: application/json" -d "{\"name\":\"string\",\"age\":\"string\"}"
    

    调试结果:
    在这里插入图片描述
    通过分析此时body发现stream长度为0
    在这里插入图片描述
    在请求到达过滤器时Steam已经被读取了,此时我们在过滤器中使用EnableBuffering并没有起作用,产生这种问题的具体原因我现在还没搞清楚。解决这个问题有个折中方案,在站点启动时设置以插入中间件的方式启用EnableBuffering,以达到在全局多次读取的目的。代码如下:

     public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
     {
     	  .....
     	  
          app.Use(next => context =>
          {
                context.Request.EnableBuffering();
                return next(context);
          });
          
          ......
     }
    

    修改过滤器中代码:

    public override void OnActionExecuting(ActionExecutingContext context)
    {
    	base.OnActionExecuting(context);
        var request = context.HttpContext.Request;
        
        if (request.Method.ToLower().Equals("post"))
        {
           request.Body.Seek(0, SeekOrigin.Begin);
           using (var reader = new StreamReader(request.Body, Encoding.UTF8))
           {
              var param = reader.ReadToEnd();
           }
            request.Body.Seek(0, SeekOrigin.Begin);
      	 } 
    }
    

    再次请求即可读取到body数据,结果如下:
    在这里插入图片描述
    此外,3.0中默认禁用了AllowSynchronousIO,同步读取body的方式需要ConfigureServices中配置允许同步读取IO流,否则可能会抛出异常 Synchronous operations are disallowed. Call ReadAsync or set AllowSynchronousIO to true instead.
    根据使用的托管的服务进行配置或直接使用异步读取方式。

    services.Configure<KestrelServerOptions>(x => x.AllowSynchronousIO = true)
                    .Configure<IISServerOptions>(x=>x.AllowSynchronousIO = true);
    
    展开全文
  • WebAPI路由、参数绑定

    千次阅读 2017-08-10 22:47:37
    a)测试Web API可以用来检测请求和返回数据是否正常,可以使用Fiddler、Postman等工具。以Fiddler为例,这是一个http协议调试代理工具,它能够记录客户端和服务器之间的所有 HTTP请求,可以针对特定的HTTP请求,分析...
  • webapi - 模型验证

    千次阅读 2017-05-24 13:46:46
    » 自定义过滤器,输出模型验证信息 » FromUri和FromBody用途   下面一步一个脚印的来分享: » 增加模型验证 首先,我们测试用例使用上一篇的 MoStudent 学生类,模型验证需要在对应提交类中的需要验证...
  • Exchange Web Service (EWS) API 使用笔记

    万次阅读 2012-04-28 13:19:41
    有时候我们需要使用程序来进行收发邮件, 传统的POP3/SMTP/IMAP等协议也正广泛的被使用着,有关这些协议的收发邮件代码网上一抓一大把~ 如果要用这些协议可以去别处看看. 我这里要谈的是使用Microsoft Exchange ...
  • 适用于WebApi的SQL注入过滤器

    千次阅读 2019-01-25 10:18:17
    但是如果是接手一个旧的WebApi项目,不想改繁多的数据库访问层的代码,应该如何做。 我的解决方案是加一个过滤器。 先写过滤方法,上代码 using System; using System.Collections.Generic; using Syst...
  • ASP.NET Core MVC/WebAPi 模型绑定探索

    千次阅读 2017-03-07 16:57:02
    前言 相信一直关注我的园友都知道,我写的博文都没有特别枯燥理论性的东西,主要是当每开启一门新的技术之旅时,刚开始就直接去看底层实现原理,第一会感觉索然无味,第二也不...在ASP.NET Core之前MVC和Web APi被分
  • Django笔记 Django REST Framework实现Web API 1

    万次阅读 多人点赞 2016-04-21 17:11:30
    本文介绍如何使用Django的REST框架来迅速开发WEBAPI。 ##Django REST Framework Django REST Framework可以在Django的基础上迅速实现API,并且自身还带有WEB的测试页面,可以方便的测试自己的API。
  • 前言 刚开始创建MVC与Web API的混合项目时,碰到好多问题,今天拿出来跟大家一起分享下。有朋友私信我问项目的分层及文件夹结构在我的第一篇博客中没说清楚,那么接下来我就准备从这些文件怎么分文件夹说起。问题...
  • 介绍了一个基于ASP.NET MVC 4、WebApi、jQuery、ajax和FormData数据对象的多文件上传方法。
  • ABP官方文档(三十)【动态WebApi层】

    千次阅读 2017-11-06 10:33:06
    5.2 ABP表现层 - 动态WebApi层5.2.1 建立动态WebApi控制 这是一篇关于ASP.NET Web API的文档。如果你对ASP.NET感兴趣,请阅读ASP.NET Core文档。 Abp框架能够通过应用层自动生成web api: public interface ...
  • 首先想到的就是request.getParameter(String )方法,但是这个方法只能在get请求中取到参数,post是不行的,后来想到了使用流的方式,调用request.getInputStream()获取流,然后从流中读取参数,如下代码所示: ...
  • 请求的URL为:...web.xml中添加过滤器 sessionFilter com.Long.api.common.SessionFilter sessionFilter /API/* spring-mvc.xml中增加拦截器的处理,其中会读到request中的inputS
  • WebApi参数传递总结

    千次阅读 2015-08-15 10:39:00
    WebApi参数传递总结 在WebAPI中,请求主体(HttpContent)只能被读取一次,不被缓存,只能向前读取的流。 举例子说明: 1. 请求地址:/?id=123&name=bob   服务端方法: void Action(int id, string name) /...
  • ASP.NET Core Web APi获取原始请求内容

    千次阅读 2019-05-09 00:37:21
    我们讲过ASP.NET Core Web APi路由绑定,本节我们来讲讲如何获取客户端请求过来的内容。 ASP.NET Core Web APi捕获Request.Body内容 [HttpPost] [Route("api/blog/jsonstring")] public string Index([FromBody] ...
  • JSP——过滤器

    万次阅读 多人点赞 2016-08-13 08:08:54
    一、过滤器的基本概念 ...用户在请求Web资源时,用户的请求会先被过滤器拦截,过滤器对用户的请求进行过滤,过滤之后过滤器再将用户的请求发送到Web资源,Web资源在将响应返回给用户时,响应也会先
  • SpringCloud——服务网关

    万次阅读 2017-01-25 14:29:53
    这篇博客我们将介绍服务网关。 图(1) 未使用服务网关的做法 图(2) 服务网关的做法 服务网关,英文Service GateWay,他是微服务框架中唯一的入口。有些类似外观模式,对外只提供一个访问的入口。...
1 2 3 4 5 ... 20
收藏数 23,674
精华内容 9,469
关键字:

webapi 过滤器获取body