增加功能:在线用户增加客户端浏览器与操作系统信息,1分钟后清理会话信息 #IS60Z
This commit is contained in:
parent
116150e60d
commit
8c9c5b5d6c
|
@ -15,7 +15,6 @@
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Bootstrap.Security.Mvc" Version="2.2.3" />
|
<PackageReference Include="Bootstrap.Security.Mvc" Version="2.2.3" />
|
||||||
<PackageReference Include="Longbow.Logging" Version="2.2.5" />
|
<PackageReference Include="Longbow.Logging" Version="2.2.5" />
|
||||||
<PackageReference Include="Longbow.Web" Version="2.2.4" />
|
|
||||||
<PackageReference Include="Microsoft.AspNetCore.App" />
|
<PackageReference Include="Microsoft.AspNetCore.App" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.Versioning" Version="3.1.2" />
|
<PackageReference Include="Microsoft.AspNetCore.Mvc.Versioning" Version="3.1.2" />
|
||||||
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="2.2.2" PrivateAssets="All" />
|
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="2.2.2" PrivateAssets="All" />
|
||||||
|
|
|
@ -19,11 +19,11 @@ namespace Bootstrap.Admin.Controllers.Api
|
||||||
[HttpPost()]
|
[HttpPost()]
|
||||||
public IEnumerable<OnlineUser> Post([FromServices]IOnlineUsers onlineUSers)
|
public IEnumerable<OnlineUser> Post([FromServices]IOnlineUsers onlineUSers)
|
||||||
{
|
{
|
||||||
return onlineUSers.OnlineUsers;
|
return onlineUSers.OnlineUsers.OrderByDescending(u => u.LastAccessTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取指定IP地址的在线用户请求地址明细数据
|
/// 获取指定会话的在线用户请求地址明细数据
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="id"></param>
|
/// <param name="id"></param>
|
||||||
/// <param name="onlineUSers"></param>
|
/// <param name="onlineUSers"></param>
|
||||||
|
@ -31,7 +31,7 @@ namespace Bootstrap.Admin.Controllers.Api
|
||||||
[HttpGet("{id}")]
|
[HttpGet("{id}")]
|
||||||
public IEnumerable<KeyValuePair<DateTime, string>> Get(string id, [FromServices]IOnlineUsers onlineUSers)
|
public IEnumerable<KeyValuePair<DateTime, string>> Get(string id, [FromServices]IOnlineUsers onlineUSers)
|
||||||
{
|
{
|
||||||
var user = onlineUSers.OnlineUsers.FirstOrDefault(u => u.Ip == id);
|
var user = onlineUSers.OnlineUsers.FirstOrDefault(u => u.ConnectionId == id);
|
||||||
return user?.RequestUrls ?? new KeyValuePair<DateTime, string>[0];
|
return user?.RequestUrls ?? new KeyValuePair<DateTime, string>[0];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,10 @@
|
||||||
using System;
|
using Longbow.Configuration;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using System;
|
||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net.Http;
|
||||||
|
|
||||||
namespace Bootstrap.Admin
|
namespace Bootstrap.Admin
|
||||||
{
|
{
|
||||||
|
@ -9,7 +13,17 @@ namespace Bootstrap.Admin
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal class DefaultOnlineUsers : IOnlineUsers
|
internal class DefaultOnlineUsers : IOnlineUsers
|
||||||
{
|
{
|
||||||
private ConcurrentDictionary<string, OnlineUser> _onlineUsers = new ConcurrentDictionary<string, OnlineUser>();
|
private ConcurrentDictionary<string, OnlineUserCache> _onlineUsers = new ConcurrentDictionary<string, OnlineUserCache>();
|
||||||
|
private HttpClient _client;
|
||||||
|
private IEnumerable<string> _local = new string[] { "::1", "127.0.0.1" };
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="factory"></param>
|
||||||
|
public DefaultOnlineUsers(IHttpClientFactory factory)
|
||||||
|
{
|
||||||
|
_client = factory.CreateClient(OnlineUsersServicesCollectionExtensions.IPSvrHttpClientName);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
|
@ -17,7 +31,7 @@ namespace Bootstrap.Admin
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public IEnumerable<OnlineUser> OnlineUsers
|
public IEnumerable<OnlineUser> OnlineUsers
|
||||||
{
|
{
|
||||||
get { return _onlineUsers.Values; }
|
get { return _onlineUsers.Values.Select(v => v.User); }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -27,6 +41,45 @@ namespace Bootstrap.Admin
|
||||||
/// <param name="addValueFactory"></param>
|
/// <param name="addValueFactory"></param>
|
||||||
/// <param name="updateValueFactory"></param>
|
/// <param name="updateValueFactory"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public OnlineUser AddOrUpdate(string key, Func<string, OnlineUser> addValueFactory, Func<string, OnlineUser, OnlineUser> updateValueFactory) => _onlineUsers.AddOrUpdate(key, addValueFactory, updateValueFactory);
|
public OnlineUserCache AddOrUpdate(string key, Func<string, OnlineUserCache> addValueFactory, Func<string, OnlineUserCache, OnlineUserCache> updateValueFactory) => _onlineUsers.AddOrUpdate(key, addValueFactory, updateValueFactory);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="key"></param>
|
||||||
|
/// <param name="onlineUserCache"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public bool TryRemove(string key, out OnlineUserCache onlineUserCache) => _onlineUsers.TryRemove(key, out onlineUserCache);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="ip"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public string RetrieveLocaleByIp(string ip = null)
|
||||||
|
{
|
||||||
|
if (ip.IsNullOrEmpty() || _local.Any(p => p == ip)) return "本地连接";
|
||||||
|
|
||||||
|
var url = ConfigurationManager.AppSettings["IPSvrUrl"];
|
||||||
|
var task = _client.GetAsJsonAsync<IPLocator>($"{url}{ip}");
|
||||||
|
task.Wait();
|
||||||
|
return task.Result.status == "0" ? string.Join(" ", task.Result.address.SpanSplit("|").Skip(1).Take(2)) : "XX XX";
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
private class IPLocator
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 详细地址信息
|
||||||
|
/// </summary>
|
||||||
|
public string address { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 结果状态返回码
|
||||||
|
/// </summary>
|
||||||
|
public string status { get; set; }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,21 @@ namespace Bootstrap.Admin
|
||||||
/// <param name="addValueFactory"></param>
|
/// <param name="addValueFactory"></param>
|
||||||
/// <param name="updateValueFactory"></param>
|
/// <param name="updateValueFactory"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
OnlineUser AddOrUpdate(string key, Func<string, OnlineUser> addValueFactory, Func<string, OnlineUser, OnlineUser> updateValueFactory);
|
OnlineUserCache AddOrUpdate(string key, Func<string, OnlineUserCache> addValueFactory, Func<string, OnlineUserCache, OnlineUserCache> updateValueFactory);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="key"></param>
|
||||||
|
/// <param name="onlineUserCache"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
bool TryRemove(string key, out OnlineUserCache onlineUserCache);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="ip"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
string RetrieveLocaleByIp(string ip = null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,11 +12,21 @@ namespace Bootstrap.Admin
|
||||||
{
|
{
|
||||||
private ConcurrentQueue<KeyValuePair<DateTime, string>> _requestUrls = new ConcurrentQueue<KeyValuePair<DateTime, string>>();
|
private ConcurrentQueue<KeyValuePair<DateTime, string>> _requestUrls = new ConcurrentQueue<KeyValuePair<DateTime, string>>();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
public string ConnectionId { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string UserName { get; set; }
|
public string UserName { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
public string DisplayName { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -27,6 +37,11 @@ namespace Bootstrap.Admin
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public DateTime LastAccessTime { get; set; }
|
public DateTime LastAccessTime { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
public string Location { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -37,6 +52,16 @@ namespace Bootstrap.Admin
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Ip { get; set; }
|
public string Ip { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
public string Browser { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
public string OS { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -0,0 +1,63 @@
|
||||||
|
using System;
|
||||||
|
using System.Threading;
|
||||||
|
|
||||||
|
namespace Bootstrap.Admin
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
public class OnlineUserCache : IDisposable
|
||||||
|
{
|
||||||
|
private Timer dispatcher;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="user"></param>
|
||||||
|
/// <param name="action"></param>
|
||||||
|
public OnlineUserCache(OnlineUser user, Action action)
|
||||||
|
{
|
||||||
|
User = user;
|
||||||
|
dispatcher = new Timer(_ => action(), null, TimeSpan.FromMinutes(1), Timeout.InfiniteTimeSpan);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
public OnlineUser User { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
public void Reset()
|
||||||
|
{
|
||||||
|
if (dispatcher != null) dispatcher.Change(TimeSpan.FromMinutes(1), Timeout.InfiniteTimeSpan);
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Impletement IDispose
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="disposing"></param>
|
||||||
|
protected virtual void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
if (disposing)
|
||||||
|
{
|
||||||
|
if (dispatcher != null)
|
||||||
|
{
|
||||||
|
dispatcher.Dispose();
|
||||||
|
dispatcher = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
Dispose(true);
|
||||||
|
GC.SuppressFinalize(this);
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,9 +1,10 @@
|
||||||
using Bootstrap.Admin;
|
using Bootstrap.Admin;
|
||||||
|
using Bootstrap.DataAccess;
|
||||||
|
using Longbow.Web;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Builder
|
namespace Microsoft.AspNetCore.Builder
|
||||||
{
|
{
|
||||||
|
@ -19,30 +20,33 @@ namespace Microsoft.AspNetCore.Builder
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static IApplicationBuilder UseOnlineUsers(this IApplicationBuilder builder) => builder.UseWhen(context => context.Filter(), app => app.Use(async (context, next) =>
|
public static IApplicationBuilder UseOnlineUsers(this IApplicationBuilder builder) => builder.UseWhen(context => context.Filter(), app => app.Use(async (context, next) =>
|
||||||
{
|
{
|
||||||
await Task.Run(() =>
|
await System.Threading.Tasks.Task.Run(() =>
|
||||||
{
|
{
|
||||||
var onlineUsers = context.RequestServices.GetService<IOnlineUsers>();
|
var onlineUserSvr = context.RequestServices.GetRequiredService<IOnlineUsers>();
|
||||||
var clientIp = context.Connection.RemoteIpAddress?.ToString() ?? "::1";
|
var proxy = new Func<OnlineUserCache, Action, OnlineUserCache>((c, action) =>
|
||||||
onlineUsers.AddOrUpdate(clientIp, key =>
|
|
||||||
{
|
|
||||||
var ou = new OnlineUser();
|
|
||||||
ou.Ip = clientIp;
|
|
||||||
ou.UserName = context.User.Identity.Name;
|
|
||||||
ou.FirstAccessTime = DateTime.Now;
|
|
||||||
ou.LastAccessTime = DateTime.Now;
|
|
||||||
ou.Method = context.Request.Method;
|
|
||||||
ou.RequestUrl = context.Request.Path;
|
|
||||||
ou.AddRequestUrl(context.Request.Path);
|
|
||||||
return ou;
|
|
||||||
}, (key, v) =>
|
|
||||||
{
|
{
|
||||||
|
var v = c.User;
|
||||||
v.UserName = context.User.Identity.Name;
|
v.UserName = context.User.Identity.Name;
|
||||||
|
if (!v.UserName.IsNullOrEmpty()) v.DisplayName = UserHelper.RetrieveUserByUserName(v.UserName).DisplayName;
|
||||||
v.LastAccessTime = DateTime.Now;
|
v.LastAccessTime = DateTime.Now;
|
||||||
v.Method = context.Request.Method;
|
v.Method = context.Request.Method;
|
||||||
v.RequestUrl = context.Request.Path;
|
v.RequestUrl = context.Request.Path;
|
||||||
v.AddRequestUrl(context.Request.Path);
|
v.AddRequestUrl(context.Request.Path);
|
||||||
return v;
|
action?.Invoke();
|
||||||
|
return c;
|
||||||
});
|
});
|
||||||
|
onlineUserSvr.AddOrUpdate(context.Connection.Id ?? "", key =>
|
||||||
|
{
|
||||||
|
var agent = new UserAgent(context.Request.Headers["User-Agent"]);
|
||||||
|
var v = new OnlineUser();
|
||||||
|
v.ConnectionId = key;
|
||||||
|
v.Ip = context.Connection.RemoteIpAddress?.ToString();
|
||||||
|
v.Location = onlineUserSvr.RetrieveLocaleByIp(v.Ip);
|
||||||
|
v.Browser = $"{agent.Browser.Name} {agent.Browser.Version}";
|
||||||
|
v.OS = $"{agent.OS.Name} {agent.OS.Version}";
|
||||||
|
v.FirstAccessTime = DateTime.Now;
|
||||||
|
return proxy(new OnlineUserCache(v, () => onlineUserSvr.TryRemove(key, out _)), null);
|
||||||
|
}, (key, v) => proxy(v, () => v.Reset()));
|
||||||
});
|
});
|
||||||
await next();
|
await next();
|
||||||
}));
|
}));
|
||||||
|
|
|
@ -8,6 +8,11 @@ namespace Microsoft.Extensions.DependencyInjection
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static class OnlineUsersServicesCollectionExtensions
|
public static class OnlineUsersServicesCollectionExtensions
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
internal const string IPSvrHttpClientName = "IPSvr";
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -16,6 +21,10 @@ namespace Microsoft.Extensions.DependencyInjection
|
||||||
public static IServiceCollection AddOnlineUsers(this IServiceCollection services)
|
public static IServiceCollection AddOnlineUsers(this IServiceCollection services)
|
||||||
{
|
{
|
||||||
services.TryAddSingleton<IOnlineUsers, DefaultOnlineUsers>();
|
services.TryAddSingleton<IOnlineUsers, DefaultOnlineUsers>();
|
||||||
|
services.AddHttpClient(IPSvrHttpClientName, client =>
|
||||||
|
{
|
||||||
|
client.DefaultRequestHeaders.Connection.Add("keep-alive");
|
||||||
|
});
|
||||||
return services;
|
return services;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,6 +49,7 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"IPSvrUrl": "http://api.map.baidu.com/location/ip?ak=6lvVPMDlm2gjLpU0aiqPsHXi2OiwGQRj&ip=",
|
||||||
"SwaggerPathBase": "/BA",
|
"SwaggerPathBase": "/BA",
|
||||||
"AllowOrigins": "http://localhost,http://10.15.63.218",
|
"AllowOrigins": "http://localhost,http://10.15.63.218",
|
||||||
"KeyPath": "..\\keys",
|
"KeyPath": "..\\keys",
|
||||||
|
|
|
@ -14,16 +14,22 @@
|
||||||
return options.pageSize * (options.pageNumber - 1) + index + 1;
|
return options.pageSize * (options.pageNumber - 1) + index + 1;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
title: "会话Id", field: "ConnectionId"
|
||||||
|
},
|
||||||
{ title: "登陆名称", field: "UserName" },
|
{ title: "登陆名称", field: "UserName" },
|
||||||
{ title: "显示名称", field: "DisplayName" },
|
{ title: "显示名称", field: "DisplayName" },
|
||||||
{ title: "登录时间", field: "FirstAccessTime" },
|
{ title: "登录时间", field: "FirstAccessTime" },
|
||||||
{ title: "最近操作时间", field: "LastAccessTime" },
|
{ title: "最近操作时间", field: "LastAccessTime" },
|
||||||
{ title: "请求方式", field: "Method" },
|
{ title: "请求方式", field: "Method" },
|
||||||
{ title: "IP地址", field: "Ip" },
|
{ title: "主机", field: "Ip" },
|
||||||
|
{ title: "登录地点", field: "Location" },
|
||||||
|
{ title: "浏览器", field: "Browser" },
|
||||||
|
{ title: "操作系统", field: "OS" },
|
||||||
{ title: "访问地址", field: "RequestUrl" },
|
{ title: "访问地址", field: "RequestUrl" },
|
||||||
{
|
{
|
||||||
title: "历史地址", field: "Ip", formatter: function (value, row, index, field) {
|
title: "历史地址", field: "ConnectionId", formatter: function (value, row, index, field) {
|
||||||
return $.format('<button type="button" class="btn btn-info" data-id="{0}" data-toggle="popover" data-trigger="focus" data-html="true" data-title="访问记录">明细</button >', value);
|
return $.format('<button type="button" class="btn btn-info" data-id="{0}" data-toggle="popover" data-trigger="focus" data-html="true" data-title="访问记录">明细</button>', value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -38,9 +44,11 @@
|
||||||
var content = result.map(function (item) {
|
var content = result.map(function (item) {
|
||||||
return $.format("<tr><td>{0}</td><td>{1}</td></tr>", item.Key, item.Value);
|
return $.format("<tr><td>{0}</td><td>{1}</td></tr>", item.Key, item.Value);
|
||||||
}).join('');
|
}).join('');
|
||||||
content = $.format('<div class="fixed-table-container"><table class="table table-hover table-sm mb-0"><thead><tr><th class="p-1"><b>访问时间</b></th><th class="p-1">访问地址</th></tr></thead><tbody>{0}</tbody></table></div>', content);
|
content = content === '' ?
|
||||||
$this.lgbPopover({ content: content, placement: $(window).width() < 768 ? 'top' : 'left' });
|
'已断开' :
|
||||||
$this.popover('show');
|
$.format('<div class="fixed-table-container"><table class="table table-hover table-sm mb-0"><thead><tr><th class="p-1"><b>访问时间</b></th><th class="p-1">访问地址</th></tr></thead><tbody>{0}</tbody></table></div>', content);
|
||||||
|
$this.popover({ content: content, placement: $(window).width() < 768 ? 'top' : 'left' });
|
||||||
|
$this.trigger('focus');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
<PackageReference Include="Bootstrap.Security.DataAccess" Version="2.1.0" />
|
<PackageReference Include="Bootstrap.Security.DataAccess" Version="2.1.0" />
|
||||||
<PackageReference Include="Longbow.Cache" Version="2.2.3" />
|
<PackageReference Include="Longbow.Cache" Version="2.2.3" />
|
||||||
<PackageReference Include="Longbow.Data" Version="2.2.6" />
|
<PackageReference Include="Longbow.Data" Version="2.2.6" />
|
||||||
<PackageReference Include="Longbow.Web" Version="2.2.4" />
|
<PackageReference Include="Longbow.Web" Version="2.2.5" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
@ -12,7 +12,6 @@
|
||||||
<PackageReference Include="Bootstrap.Security.Mvc" Version="2.2.3" />
|
<PackageReference Include="Bootstrap.Security.Mvc" Version="2.2.3" />
|
||||||
<PackageReference Include="Longbow.Cache" Version="2.2.3" />
|
<PackageReference Include="Longbow.Cache" Version="2.2.3" />
|
||||||
<PackageReference Include="Longbow.Logging" Version="2.2.5" />
|
<PackageReference Include="Longbow.Logging" Version="2.2.5" />
|
||||||
<PackageReference Include="Longbow.Web" Version="2.2.4" />
|
|
||||||
<PackageReference Include="Microsoft.AspNetCore.App" />
|
<PackageReference Include="Microsoft.AspNetCore.App" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
<PackageReference Include="Bootstrap.Security.DataAccess" Version="2.1.0" />
|
<PackageReference Include="Bootstrap.Security.DataAccess" Version="2.1.0" />
|
||||||
<PackageReference Include="Longbow.Data" Version="2.2.6" />
|
<PackageReference Include="Longbow.Data" Version="2.2.6" />
|
||||||
<PackageReference Include="Longbow.Security.Cryptography" Version="1.3.0" />
|
<PackageReference Include="Longbow.Security.Cryptography" Version="1.3.0" />
|
||||||
<PackageReference Include="Longbow.Web" Version="2.2.4" />
|
<PackageReference Include="Longbow.Web" Version="2.2.5" />
|
||||||
<PackageReference Include="Longbow.Cache" Version="2.2.3" />
|
<PackageReference Include="Longbow.Cache" Version="2.2.3" />
|
||||||
<PackageReference Include="Longbow" Version="2.2.7" />
|
<PackageReference Include="Longbow" Version="2.2.7" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
using Bootstrap.Security;
|
using Bootstrap.Security;
|
||||||
using Longbow.Cache;
|
using Longbow.Cache;
|
||||||
using Longbow.Data;
|
using Longbow.Data;
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace Bootstrap.DataAccess
|
namespace Bootstrap.DataAccess
|
||||||
|
|
|
@ -73,7 +73,12 @@ namespace Bootstrap.Admin
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="baseAddress"></param>
|
/// <param name="baseAddress"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public HttpClient CreateClient(string baseAddress) => CreateDefaultClient(new Uri($"http://localhost/{baseAddress}/"), new RedirectHandler(7), new CookieContainerHandler(_cookie));
|
public HttpClient CreateClient(string baseAddress)
|
||||||
|
{
|
||||||
|
var client = CreateDefaultClient(new Uri($"http://localhost/{baseAddress}/"), new RedirectHandler(7), new CookieContainerHandler(_cookie));
|
||||||
|
client.DefaultRequestHeaders.Add("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_1) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.0.1 Safari/605.1.15");
|
||||||
|
return client;
|
||||||
|
}
|
||||||
|
|
||||||
private readonly CookieContainer _cookie = new CookieContainer();
|
private readonly CookieContainer _cookie = new CookieContainer();
|
||||||
|
|
||||||
|
|
|
@ -11,15 +11,15 @@ namespace Bootstrap.Admin.Api
|
||||||
[Fact]
|
[Fact]
|
||||||
public async void Post_Ok()
|
public async void Post_Ok()
|
||||||
{
|
{
|
||||||
var usres = await Client.PostAsJsonAsync<string, IEnumerable<OnlineUser>>(string.Empty);
|
var users = await Client.PostAsJsonAsync<string, IEnumerable<OnlineUser>>(string.Empty);
|
||||||
Assert.Single(usres);
|
Assert.Single(users);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async void Get_Ok()
|
public async void Get_Ok()
|
||||||
{
|
{
|
||||||
var urls = await Client.GetAsJsonAsync<IEnumerable<KeyValuePair<DateTime, string>>>("::1");
|
var urls = await Client.GetAsJsonAsync<IEnumerable<KeyValuePair<DateTime, string>>>("UnitTest");
|
||||||
Assert.NotEmpty(urls);
|
Assert.Empty(urls);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue