微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Miniprofiler在swagger、vue、angular中的使用

 本篇分为以下几个部分:

 

Swagger的简单应用

1、首先新建一个Api项目

分享图片

 

2、使用Nuget添加Swashbuckle.AspNetCore,我使用的版本为1.1.0( 版本不一样,后面的配置可能不一样
 
3、为了在swagger上显示注释,右键项目MiniprofilerApi,属性=>生成=>输出为XML文档文件
 
4、右键项目=>编辑.csproj添加如下代码,避免一些警告:
 

分享图片

 

4、在Startup类的ConfigureServices方法和Configure方法中配置如下:

分享图片

分享图片

 

5、添加接口注释:

分享图片

 

6、修改项目运行端口,访问路径,关闭ssl,右键项目=>属性=>调试,配置如下:

分享图片

 

7、启动项目,界面效果如下:

分享图片

Miniprofier的后台配置

1、安装MiniProfiler.AspNetCore.Mvc

2、在Startup类的ConfigureServices方法和Configure方法中配置如下:

分享图片

分享图片

 

3、运行程序:访问http://localhost:5000/mini-profiler-resources/results

分享图片

 

跨域配置:

分享图片

分享图片

 

在angular中显示Miniprofier

1、在页面创建Miniprofier需要的js和css

分享图片

import { Component } from ‘@angular/core‘;
import { HttpClient } from ‘@angular/common/http‘;


@Component({
  selector: ‘app-root‘,templateUrl: ‘./app.component.html‘,styleUrls: [‘./app.component.css‘]
})
export class AppComponent {

  private src: string = ‘http://localhost:5000/mini-profiler-resources/‘;
  private scriptSrc: string = `${this.src}includes.min.js`;
  private cssSrc: string = `${this.src}includes.min.css`;

  private id: string = ‘mini-profiler‘;
  private dataPath: string = `${this.src}`;
  private dataVersion: string = ‘‘;
  private dataPosition: string = ‘right‘;
  private dataChildren: boolean = true;
  private dataMaxTraces: number = 35;
  private dataAuthorized: boolean = true;
  private dataStartHidden: string = ‘false‘;
  private dataToggleShortcut: string = ‘Alt+P‘;
  private dataTrivialMilliseconds: number = 35;
  private dataTrivial: boolean = true;
  private dataControls: boolean = true;
  private dataCurrentId: string = ‘‘;
  private dataIds: string = ‘‘;
  private scriptAsync: boolean = true;
  private innerHTML: string = ‘‘;

  constructor(private http: HttpClient){
  }

  ngAfterViewInit(): void {
    //添加Miniprofier的js
    this.appenddivelement();
    //添加Miniprofier的css
    this.appendCssLink();
  }

  //请求后台接口
  send(): void{
    let serverurl: string = "http://localhost:5000//api/Values";

    this.http.get(serverurl)
    .toPromise()
    .then(response => {
      console.log()
    }).catch(error => {
    });
  }

  private appenddivelement(): void {
    const body = document.body as HTMLdivelement;
    const script = document.createElement(‘script‘);
    script.innerHTML = this.innerHTML;
    script.src = this.scriptSrc;
    script.setAttribute(‘data-version‘,this.dataVersion);
    script.setAttribute(‘data-path‘,this.dataPath);
    script.setAttribute(‘data-position‘,this.dataPosition);
    script.setAttribute(‘id‘,this.id);
    script.setAttribute(‘data-current-id‘,this.dataCurrentId);
    script.setAttribute(‘data-ids‘,this.dataIds);
    script.setAttribute(‘data-trivial‘,this.dataTrivial.toString());
    script.setAttribute(‘data-children‘,this.dataChildren.toString());
    script.setAttribute(‘data-max-traces‘,this.dataMaxTraces.toString());
    script.setAttribute(‘data-controls‘,this.dataControls.toString());
    script.setAttribute(‘data-authorized‘,this.dataAuthorized.toString());
    script.setAttribute(‘data-start-hidden‘,this.dataStartHidden.toString());
    script.setAttribute(‘data-toggle-shortcut‘,this.dataToggleShortcut);
    script.setAttribute(‘data-trivial-milliseconds‘,this.dataTrivialMilliseconds.toString());
    script.async = this.scriptAsync;
    body.appendChild(script);
  }

  private appendCssLink(): void {
      const body = document.body as HTMLdivelement;
      const css = document.createElement(‘link‘);
      css.href = this.cssSrc;
      css.rel = ‘stylesheet‘;

      body.appendChild(css);
  }
}
View Code

2、添加Http拦截器,动态显示监听结果

分享图片

import { Injectable } from ‘@angular/core‘;
import { HttpInterceptor,HttpHandler,HttpRequest,HttpEvent,HttpResponse,HttpHeaders }
  from ‘@angular/common/http‘;

import { Observable } from ‘rxjs‘;
import { tap } from ‘rxjs/operators‘;

declare var MiniProfiler: any;

@Injectable()
export class MiniProfilerInterceptor implements HttpInterceptor {
  intercept(
    req: HttpRequest<any>,next: HttpHandler
  ): Observable<HttpEvent<any>> {
    return next.handle(req).pipe(
        tap(evt => {
            if (evt instanceof HttpResponse) {
              if (evt && evt.headers) {
                this.makeMiniProfilerRequests(evt.headers);
              }
            }
          })
    )
  }

  private makeMiniProfilerRequests(headers: HttpHeaders) {
    const miniProfilerHeaders = headers.getAll(‘x-miniprofiler-ids‘);

    if (!miniProfilerHeaders) {
      return;
    }

    miniProfilerHeaders.forEach(miniProfilerIdHeaderValue => {
      const ids = JSON.parse(miniProfilerIdHeaderValue) as string[];
      MiniProfiler.fetchResults(ids);
    });

  }
}
View Code

3、在app.module.ts中的配置

分享图片

import { browserModule } from ‘@angular/platform-browser‘;
import { NgModule } from ‘@angular/core‘;

import { AppComponent } from ‘./app.component‘;
import { HttpClientModule,HTTP_INTERCEPTORS } from ‘@angular/common/http‘;
import { MiniProfilerInterceptor } from ‘./mini-profiler-http‘;

@NgModule({
  declarations: [
    AppComponent
  ],imports: [
    browserModule,HttpClientModule
  ],providers: [{
    provide: HTTP_INTERCEPTORS,useClass: MiniProfilerInterceptor,multi: true
  }],bootstrap: [AppComponent]
})
export class AppModule { }
View Code

4、在app.component.html页面添加一个请求按钮

分享图片

<div style="text-align:center;margin:100px auto">
  <button (click)="send()">click</button>
</div>
View Code

5、页面效果

分享图片

 

在vue中显示Miniprofier

和在angular中的操作步骤一致,下面放主要代码

1、App.vue 主组件

分享图片

<template>
  <div id="app">
    <MiniProfiler 
      :scriptSrc="scriptSrc"
      :dataPath="src"
      :cssSrc="cssSrc"/>
      <Dummy />
  </div>
</template>

<script lang="ts">
import { Component,Vue } from vue-property-decorator;
import MiniProfiler from ‘./components/MiniProfiler.vue‘;
import Dummy from ‘./components/Dummy.vue‘;
import axios from ‘axios‘;

@Component({
  components: {
    MiniProfiler,Dummy,},})
export default class App extends Vue {
  private src: string = ‘http://localhost:5000/mini-profiler-resources/‘;
  private scriptSrc: string = `${this.src}includes.min.js`;
  private cssSrc: string = `${this.src}includes.min.css`;
}
</script>

<style>
#app {
  font-family: ‘Avenir‘,Helvetica,Arial,sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>
View Code

 

2、Dummy.vue 子组件用于发送接口请求

分享图片

<template>
    <button type="button" @click="getProfiler">Click Me!</button> 
</template>

<script lang="ts">
import { Component,Vue } from vue-property-decorator;
import axios from ‘axios‘;

@Component
export default class Dummy extends Vue {
    private getProfiler() {
        axios.get(‘http://localhost:5000/api/values‘);
    }
}
</script>
View Code

 

3、MiniProfiler.vue 子组件用于添加拦截器和创建Miniprofier需要的js和css

分享图片

<template>
</template>

<script lang="ts">
import { Component,Prop,Vue } from vue-property-decorator;
import axios from ‘axios‘;

@Component
export default class MiniProfiler extends Vue {
    @Prop({ default: ‘mini-profiler‘ }) private id!: string;
    @Prop() private scriptSrc!: string;
    @Prop() private cssSrc!: string;
    @Prop() private dataPath!: string;
    @Prop({ default: ‘‘ }) private dataVersion!: string;
    @Prop({ default: ‘right‘ }) private dataPosition!: string;
    @Prop({ default: true }) private dataChildren!: boolean;
    @Prop({ default: 35 }) private dataMaxTraces!: number;
    @Prop({ default: true }) private dataAuthorized!: boolean;
    @Prop({ default: false }) private dataStartHidden!: string;
    @Prop({ default: ‘Alt+P‘ }) private dataToggleShortcut!: string;
    @Prop({ default: 35 }) private dataTrivialMilliseconds!: number;
    @Prop({ default: true }) private dataTrivial!: boolean;
    @Prop({ default: true }) private dataControls!: boolean;
    @Prop({ default: ‘‘ }) private dataCurrentId!: string;
    @Prop({ default: ‘‘ }) private dataIds!: string;
    @Prop({ default: true }) private scriptAsync!: boolean;
    @Prop({ default: ‘‘ }) private innerHTML!: string;

    private created(): void {
        this.axiosSetUp();
        this.appenddivelement();
        this.appendCssLink();
    }

    private axiosSetUp(): void {
        const key: string = ‘MiniProfiler‘;
        axios.interceptors.response.use(function success(config) {
            const miniProfiler: any = (window as any)[key];

            const miniProfilerIds = JSON.parse(config.headers[‘x-miniprofiler-ids‘]) as string[];
            miniProfiler.fetchResults(miniProfilerIds);
            return config;
        },function bug(error) {
            return Promise.reject(error);
        });
    }

    private appenddivelement(): void {
        const body = document.body as HTMLdivelement;
        const script = document.createElement(‘script‘);
        script.innerHTML = this.innerHTML;
        script.src = this.scriptSrc;
        script.setAttribute(‘data-version‘,this.dataVersion);
        script.setAttribute(‘data-path‘,this.dataPath);
        script.setAttribute(‘data-position‘,this.dataPosition);
        script.setAttribute(‘id‘,this.id);
        script.setAttribute(‘data-current-id‘,this.dataCurrentId);
        script.setAttribute(‘data-ids‘,this.dataIds);
        script.setAttribute(‘data-trivial‘,this.dataTrivial.toString());
        script.setAttribute(‘data-children‘,this.dataChildren.toString());
        script.setAttribute(‘data-max-traces‘,this.dataMaxTraces.toString());
        script.setAttribute(‘data-controls‘,this.dataControls.toString());
        script.setAttribute(‘data-authorized‘,this.dataAuthorized.toString());
        script.setAttribute(‘data-start-hidden‘,this.dataStartHidden.toString());
        script.setAttribute(‘data-toggle-shortcut‘,this.dataToggleShortcut);
        script.setAttribute(‘data-trivial-milliseconds‘,this.dataTrivialMilliseconds.toString());
        script.async = this.scriptAsync;

        body.appendChild(script);
    }

    private appendCssLink(): void {
        const body = document.body as HTMLdivelement;
        const css = document.createElement(‘link‘);
        css.href = this.cssSrc;
        css.rel = ‘stylesheet‘;

        body.appendChild(css);
    }
}
</script>
View Code

 

4、界面效果

 

分享图片

 

在swagger中显示Miniprofier

1、将性能分析监测信息从后端发送到Swagger界面。

首先给swagger添加拦截

分享图片

 

拦截代码如下:

分享图片

using Microsoft.AspNetCore.Http;
using StackExchange.Profiling;
using Swashbuckle.AspNetCore.Swagger;
using Swashbuckle.AspNetCore.SwaggerGen;

namespace MiniprofilerApi.MiniProfierHelp
{
    public class InjectMiniProfiler : IDocumentFilter
    {
        private readonly IHttpContextAccessor _httpContext;
        public InjectMiniProfiler(IHttpContextAccessor httpContext)
        {
            _httpContext = httpContext;
        }
        public void Apply(SwaggerDocument swaggerDoc,DocumentFilterContext context)
        {
            swaggerDoc.Info.Contact = new Contact()
            {
                Name = MiniProfiler.Current.RenderIncludes(_httpContext.HttpContext).ToString()
            };
        }
    }
}
View Code

 

此时运行项目,swagger界面显示如下:

分享图片

2、通过js解析MIniprofier的脚本,代码如下:

分享图片

(function () {
    window.angular=true;

    //Create a mini profiler script tag with the right properites 
    var MiniProfiler = $(‘#api_info > div:nth-child(3)‘).text();

    const attributes = [
        ‘src‘,‘data-version‘,‘data-path‘,‘data-current-id‘,‘data-ids‘,‘data-position‘,‘data-trivial-milliseconds‘,‘data-max-traces‘,‘data-authorized‘,‘data-toggle-shortcut‘,‘data-ignored-duplicate-execute-types‘
    ];

    var GetAttr = function (input,attributeName) {
        const myRegexp = attributeName + ‘="(.*?)"‘;
        const re = new RegExp(myRegexp,"g");
        const match = re.exec(input);
        return match[1];
    }
    var s = document.createElement("script");
    s.type = "text/javascript";
    s.id = "mini-profiler";
    s.async = true; 

    for (var i = 0; i < attributes.length; i++) {
        var element = attributes[i];
        s.setAttribute(element,GetAttr(MiniProfiler,element));
    }

    document.body.appendChild(s);

    // Remove injected tag from view 
    $(‘#api_info > div:nth-child(3)‘).text(‘‘);
})();
View Code

配置swagger执行js:

分享图片

 

3、界面效果如下:

分享图片

 

全部源代码见:https://github.com/MrGuoKe/Miniprofiler.git

 

监听EF执行的sql语句或更多NetCore+Miniprofiler相关配置见:https://miniprofiler.com/dotnet/AspDotNetCore

 

更多Swagger+NetCore配置见:https://docs.microsoft.com/en-us/aspnet/core/tutorials/getting-started-with-swashbuckle?view=aspnetcore-2.2&tabs=visual-studio

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐