diff --git a/Blog.Core.AdminMvc/Blog.Core.AdminMvc.csproj b/Blog.Core.AdminMvc/Blog.Core.AdminMvc.csproj
deleted file mode 100644
index 57f47e0..0000000
--- a/Blog.Core.AdminMvc/Blog.Core.AdminMvc.csproj
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-
- net5.0
-
-
-
-
-
-
-
diff --git a/Blog.Core.AdminMvc/Startup.cs b/Blog.Core.AdminMvc/Startup.cs
deleted file mode 100644
index a9bf97b..0000000
--- a/Blog.Core.AdminMvc/Startup.cs
+++ /dev/null
@@ -1,38 +0,0 @@
-using Microsoft.AspNetCore.Builder;
-using Microsoft.AspNetCore.Hosting;
-using Microsoft.Extensions.DependencyInjection;
-using Microsoft.Extensions.Hosting;
-using Ocelot.DependencyInjection;
-using Ocelot.Middleware;
-
-namespace Blog.Core.AdminMvc
-{
- public class Startup
- {
- /**
- *┌──────────────────────────────────────────────────────────────┐
- *│ 描 述:当前项目为空,只是模拟一个MVC客户端
- *│ 作 者:anson zhang
- *└──────────────────────────────────────────────────────────────┘
- */
-
-
- // This method gets called by the runtime. Use this method to add services to the container.
- // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
- public void ConfigureServices(IServiceCollection services)
- {
- services.AddOcelot();
- }
-
- // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
- public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
- {
- if (env.IsDevelopment())
- {
- app.UseDeveloperExceptionPage();
- }
-
- app.UseOcelot().Wait();
- }
- }
-}
diff --git a/Blog.Core.AdminMvc/appsettings.json b/Blog.Core.AdminMvc/appsettings.json
deleted file mode 100644
index 9e3249b..0000000
--- a/Blog.Core.AdminMvc/appsettings.json
+++ /dev/null
@@ -1,17 +0,0 @@
-{
- "Logging": {
- "IncludeScopes": false,
- "Debug": {
- "LogLevel": {
- "Default": "Warning"
- }
- },
- "Console": {
- "LogLevel": {
- "Default": "Warning",
- "Microsoft.Hosting.Lifetime": "Debug"
- }
- }
- },
- "AllowedHosts": "*"
-}
diff --git a/Blog.Core.Api/appsettings.json b/Blog.Core.Api/appsettings.json
index b35ae50..63f6c84 100644
--- a/Blog.Core.Api/appsettings.json
+++ b/Blog.Core.Api/appsettings.json
@@ -169,7 +169,7 @@
"Enabled": true
},
"Consul": {
- "Enabled": false
+ "Enabled": true
},
"IpRateLimit": {
"Enabled": true
diff --git a/Blog.Core.Extensions/Authorizations/Policys/ApiResponseHandler.cs b/Blog.Core.Extensions/Authorizations/Policys/ApiResponseHandler.cs
index 3ee0387..6aedc54 100644
--- a/Blog.Core.Extensions/Authorizations/Policys/ApiResponseHandler.cs
+++ b/Blog.Core.Extensions/Authorizations/Policys/ApiResponseHandler.cs
@@ -1,4 +1,4 @@
-using Blog.Core.AuthHelper.Policys;
+using Blog.Core.Model;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
diff --git a/Blog.Core.Extensions/Middlewares/ExceptionHandlerMidd.cs b/Blog.Core.Extensions/Middlewares/ExceptionHandlerMidd.cs
index 0f8c385..056bc6c 100644
--- a/Blog.Core.Extensions/Middlewares/ExceptionHandlerMidd.cs
+++ b/Blog.Core.Extensions/Middlewares/ExceptionHandlerMidd.cs
@@ -1,4 +1,4 @@
-using Blog.Core.AuthHelper.Policys;
+using Blog.Core.Model;
using Microsoft.AspNetCore.Http;
using Newtonsoft.Json;
using System;
diff --git a/Blog.Core.Extensions/ServiceExtensions/AppConfigSetup.cs b/Blog.Core.Extensions/ServiceExtensions/AppConfigSetup.cs
index 1223a06..df3da09 100644
--- a/Blog.Core.Extensions/ServiceExtensions/AppConfigSetup.cs
+++ b/Blog.Core.Extensions/ServiceExtensions/AppConfigSetup.cs
@@ -139,6 +139,16 @@ namespace Blog.Core.Extensions
ConsoleHelper.WriteSuccessLine($"RabbitMQ: True");
}
+ // Consul 注册服务
+ if (!Appsettings.app("Middleware", "Consul", "Enabled").ObjToBool())
+ {
+ Console.WriteLine($"Consul service: False");
+ }
+ else
+ {
+ ConsoleHelper.WriteSuccessLine($"Consul service: True");
+ }
+
// EventBus 事件总线
if (!Appsettings.app("EventBus", "Enabled").ObjToBool())
{
diff --git a/Blog.Core.Gateway/Blog.Core.Gateway.csproj b/Blog.Core.Gateway/Blog.Core.Gateway.csproj
new file mode 100644
index 0000000..09f6dee
--- /dev/null
+++ b/Blog.Core.Gateway/Blog.Core.Gateway.csproj
@@ -0,0 +1,26 @@
+
+
+
+ net5.0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Blog.Core.Gateway/Controllers/UserController.cs b/Blog.Core.Gateway/Controllers/UserController.cs
new file mode 100644
index 0000000..b03889a
--- /dev/null
+++ b/Blog.Core.Gateway/Controllers/UserController.cs
@@ -0,0 +1,32 @@
+using Blog.Core.Common.HttpContextUser;
+using Blog.Core.Model;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+using System.Collections.Generic;
+using System.Linq;
+using System.Security.Claims;
+
+namespace Blog.Core.Gateway.Controllers
+{
+ [Authorize]
+ [Route("/gateway/[controller]/[action]")]
+ public class UserController : ControllerBase
+ {
+ private readonly IUser _user;
+
+ public UserController(IUser user)
+ {
+ _user = user;
+ }
+
+ [HttpGet]
+ public MessageModel> MyClaims()
+ {
+ return new MessageModel>()
+ {
+ success = true,
+ response = _user.GetClaimsIdentity().ToList()
+ };
+ }
+ }
+}
diff --git a/Blog.Core.Gateway/Extensions/ApiResponseHandler.cs b/Blog.Core.Gateway/Extensions/ApiResponseHandler.cs
new file mode 100644
index 0000000..c4af645
--- /dev/null
+++ b/Blog.Core.Gateway/Extensions/ApiResponseHandler.cs
@@ -0,0 +1,77 @@
+using Blog.Core.Model;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Serialization;
+using System;
+using System.Net;
+using System.Net.Http;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace Blog.Core.Gateway.Extensions
+{
+ ///
+ /// 这里不需要,目前集成的是 Blog.Core.Extensions 下的接口处理器
+ /// 但是你可以单独在网关中使用这个。
+ ///
+ public class ApiResponseHandler : DelegatingHandler
+ {
+ JsonSerializerSettings jsonSerializerSettings = new JsonSerializerSettings()
+ {
+ ContractResolver = new CamelCasePropertyNamesContractResolver()
+ };
+
+ protected async override Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
+ {
+ var response = await base.SendAsync(request, cancellationToken);
+ var contentType = response.Content.Headers.ContentType?.MediaType ?? "";
+ if (!contentType.Equals("application/json")) return response;
+
+ dynamic result = null;
+ var resultStr = await response.Content.ReadAsStringAsync();
+ try
+ {
+ result = JsonConvert.DeserializeObject(resultStr);
+ }
+ catch (Exception)
+ {
+ return response;
+ }
+
+ if (result != null && result.code == 500) resultStr = result.msg.ToString();
+
+ var apiResponse = new ApiResponse(StatusCode.CODE200).MessageModel;
+ if (response.StatusCode != HttpStatusCode.OK || result.code == (int)HttpStatusCode.InternalServerError)
+ {
+ var exception = new Exception(resultStr);
+ apiResponse = new ApiResponse(StatusCode.CODE500).MessageModel;
+ }
+ else if (result.code == (int)HttpStatusCode.Unauthorized)
+ {
+ apiResponse = new ApiResponse(StatusCode.CODE401).MessageModel;
+
+ }
+ else if (result.code == (int)HttpStatusCode.Forbidden)
+ {
+ apiResponse = new ApiResponse(StatusCode.CODE403).MessageModel;
+
+ }
+ else
+ {
+
+ }
+
+ var statusCode = apiResponse.status == 500 ? HttpStatusCode.InternalServerError
+ : apiResponse.status == 401 ? HttpStatusCode.Unauthorized
+ : apiResponse.status == 403 ? HttpStatusCode.Forbidden
+ : HttpStatusCode.OK;
+
+ response.StatusCode = statusCode;
+ response.Content = new StringContent(JsonConvert.SerializeObject(apiResponse, jsonSerializerSettings), Encoding.UTF8, "application/json");
+
+ return response;
+ }
+ }
+
+
+}
diff --git a/Blog.Core.Gateway/Extensions/OcelotMildd.cs b/Blog.Core.Gateway/Extensions/OcelotMildd.cs
new file mode 100644
index 0000000..d8e3393
--- /dev/null
+++ b/Blog.Core.Gateway/Extensions/OcelotMildd.cs
@@ -0,0 +1,16 @@
+using Microsoft.AspNetCore.Builder;
+using Ocelot.Middleware;
+using System.Threading.Tasks;
+
+namespace Blog.Core.Gateway.Extensions
+{
+ public static class OcelotMildd
+ {
+ public static async Task UseOcelotMildd(this IApplicationBuilder app)
+ {
+ await app.UseOcelot();
+ return app;
+ }
+
+ }
+}
diff --git a/Blog.Core.AdminMvc/OcelotGatewaySet.json b/Blog.Core.Gateway/OcelotGatewaySet.json
similarity index 82%
rename from Blog.Core.AdminMvc/OcelotGatewaySet.json
rename to Blog.Core.Gateway/OcelotGatewaySet.json
index be4292c..362529e 100644
--- a/Blog.Core.AdminMvc/OcelotGatewaySet.json
+++ b/Blog.Core.Gateway/OcelotGatewaySet.json
@@ -1,14 +1,6 @@
{
"Routes": [
{
- "DownstreamPathTemplate": "/api/{url}",
- "DownstreamScheme": "http",
- "DownstreamHostAndPorts": [
- {
- "Host": "localhost",
- "Port": 8081
- }
- ],
"UpstreamPathTemplate": "/gateway/api/{url}",
"UpstreamHttpMethod": [
"Get",
@@ -18,17 +10,17 @@
],
"LoadBalancerOptions": {
"Type": "RoundRobin"
- }
- },
- {
- "DownstreamPathTemplate": "/is4api/{url}",
+ },
+ "DownstreamPathTemplate": "/api/{url}",
"DownstreamScheme": "http",
"DownstreamHostAndPorts": [
{
"Host": "localhost",
- "Port": 5004
+ "Port": 8081
}
- ],
+ ]
+ },
+ {
"UpstreamPathTemplate": "/gateway/is4api/{url}",
"UpstreamHttpMethod": [
"Get",
@@ -38,10 +30,23 @@
],
"LoadBalancerOptions": {
"Type": "RoundRobin"
- }
+ },
+ "DownstreamPathTemplate": "/is4api/{url}",
+ "DownstreamScheme": "http",
+ "DownstreamHostAndPorts": [
+ {
+ "Host": "localhost",
+ "Port": 5004
+ }
+ ]
}
],
"GlobalConfiguration": {
- "BaseUrl": "http://localhost:9000"
+ "BaseUrl": "http://localhost:9000",
+ "ServiceDiscoveryProvider": {
+ "Host": "localhost",
+ "Port": 8500,
+ "Type": "Consul"
+ }
}
}
\ No newline at end of file
diff --git a/Blog.Core.AdminMvc/Program.cs b/Blog.Core.Gateway/Program.cs
similarity index 100%
rename from Blog.Core.AdminMvc/Program.cs
rename to Blog.Core.Gateway/Program.cs
diff --git a/Blog.Core.AdminMvc/Properties/launchSettings.json b/Blog.Core.Gateway/Properties/launchSettings.json
similarity index 89%
rename from Blog.Core.AdminMvc/Properties/launchSettings.json
rename to Blog.Core.Gateway/Properties/launchSettings.json
index 218573b..6265ef3 100644
--- a/Blog.Core.AdminMvc/Properties/launchSettings.json
+++ b/Blog.Core.Gateway/Properties/launchSettings.json
@@ -1,6 +1,6 @@
{
"profiles": {
- "Blog.Core.AdminMvc": {
+ "Blog.Core.Gateway": {
"commandName": "Project",
"launchBrowser": true,
"applicationUrl": "http://localhost:9000",
diff --git a/Blog.Core.Gateway/Startup.cs b/Blog.Core.Gateway/Startup.cs
new file mode 100644
index 0000000..5f98e1c
--- /dev/null
+++ b/Blog.Core.Gateway/Startup.cs
@@ -0,0 +1,76 @@
+using Blog.Core.Common;
+using Blog.Core.Extensions;
+using Blog.Core.Gateway.Extensions;
+using Microsoft.AspNetCore.Builder;
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Hosting;
+using Ocelot.DependencyInjection;
+using Ocelot.Provider.Consul;
+
+namespace Blog.Core.AdminMvc
+{
+ public class Startup
+ {
+ /**
+ *┌──────────────────────────────────────────────────────────────┐
+ *│ 描 述:模拟一个网关项目
+ *│ 测 试:http://localhost:9000/gateway/user/MyClaims
+ *│ 测 试:http://localhost:9000/gateway/api/blog
+ *│ 测 试:http://localhost:9000/gateway/is4api/GetAchieveUsers
+ *│ 作 者:anson zhang
+ *└──────────────────────────────────────────────────────────────┘
+ */
+ public Startup(IConfiguration configuration, IWebHostEnvironment env)
+ {
+ Configuration = configuration;
+ }
+
+ public IConfiguration Configuration { get; }
+
+ // This method gets called by the runtime. Use this method to add services to the container.
+ // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
+ public void ConfigureServices(IServiceCollection services)
+ {
+ services.AddSingleton(new Appsettings(Configuration));
+
+ services.AddAuthentication_JWTSetup();
+
+ services.AddAuthorization(options =>
+ {
+ options.AddPolicy("GW", policy => policy.RequireRole("GW").Build());
+ });
+
+ services.AddControllers();
+
+ services.AddHttpContextSetup();
+
+ services.AddCorsSetup();
+
+ services.AddOcelot().AddConsul();
+ }
+
+ // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
+ public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
+ {
+ if (env.IsDevelopment())
+ {
+ app.UseDeveloperExceptionPage();
+ }
+
+ app.UseRouting();
+
+ app.UseAuthorization();
+
+ app.UseCors(Appsettings.app(new string[] { "Startup", "Cors", "PolicyName" }));
+
+ app.UseEndpoints(endpoints =>
+ {
+ endpoints.MapControllers();
+ });
+
+ app.UseOcelotMildd().Wait();
+ }
+ }
+}
diff --git a/Blog.Core.AdminMvc/appsettings.Development.json b/Blog.Core.Gateway/appsettings.Development.json
similarity index 100%
rename from Blog.Core.AdminMvc/appsettings.Development.json
rename to Blog.Core.Gateway/appsettings.Development.json
diff --git a/Blog.Core.Gateway/appsettings.json b/Blog.Core.Gateway/appsettings.json
new file mode 100644
index 0000000..59f40d8
--- /dev/null
+++ b/Blog.Core.Gateway/appsettings.json
@@ -0,0 +1,31 @@
+{
+ "Logging": {
+ "IncludeScopes": false,
+ "Debug": {
+ "LogLevel": {
+ "Default": "Warning"
+ }
+ },
+ "Console": {
+ "LogLevel": {
+ "Default": "Warning",
+ "Microsoft.Hosting.Lifetime": "Debug"
+ }
+ }
+ },
+ "AllowedHosts": "*",
+ "Startup": {
+ "Cors": {
+ "PolicyName": "CorsIpAccess",
+ "EnableAllIPs": false,
+ "IPs": "http://127.0.0.1:2364,http://localhost:2364"
+ }
+ },
+ "Audience": {
+ "Secret": "sdfsdfsrty45634kkhllghtdgdfss345t678fs",
+ "SecretFile": "C:\\my-file\\blog.core.audience.secret.txt",
+ "Issuer": "Blog.Core",
+ "Audience": "wr"
+ }
+
+}
diff --git a/Blog.Core.Extensions/Authorizations/Policys/ApiResponse.cs b/Blog.Core.Model/ApiResponse.cs
similarity index 75%
rename from Blog.Core.Extensions/Authorizations/Policys/ApiResponse.cs
rename to Blog.Core.Model/ApiResponse.cs
index 014845a..0927aca 100644
--- a/Blog.Core.Extensions/Authorizations/Policys/ApiResponse.cs
+++ b/Blog.Core.Model/ApiResponse.cs
@@ -1,11 +1,10 @@
-using Blog.Core.Model;
-
-namespace Blog.Core.AuthHelper.Policys
+
+namespace Blog.Core.Model
{
public class ApiResponse
{
- public int Status { get; set; } = 404;
- public string Value { get; set; } = "No Found";
+ public int Status { get; set; } = 200;
+ public string Value { get; set; } = "";
public MessageModel MessageModel = new MessageModel() { };
public ApiResponse(StatusCode apiCode, string msg = null)
@@ -24,6 +23,12 @@ namespace Blog.Core.AuthHelper.Policys
Value = "很抱歉,您的访问权限等级不够,联系管理员!";
}
break;
+ case StatusCode.CODE404:
+ {
+ Status = 404;
+ Value = "资源不存在!";
+ }
+ break;
case StatusCode.CODE500:
{
Status = 500;
@@ -36,13 +41,14 @@ namespace Blog.Core.AuthHelper.Policys
{
status = Status,
msg = Value,
- success = false
+ success = apiCode != StatusCode.CODE200
};
}
}
public enum StatusCode
{
+ CODE200,
CODE401,
CODE403,
CODE404,
diff --git a/Blog.Core.sln b/Blog.Core.sln
index da69603..10cc592 100644
--- a/Blog.Core.sln
+++ b/Blog.Core.sln
@@ -15,17 +15,11 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Blog.Core.Services", "Blog.
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Blog.Core.Common", "Blog.Core.Common\Blog.Core.Common.csproj", "{97D32A49-994C-44C5-A167-51E71D173B6F}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Blog.Core.FrameWork", "Blog.Core.FrameWork\Blog.Core.FrameWork.csproj", "{44A2006E-3EFC-4179-B400-866178C66556}"
-EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Blog.Core.Tasks", "Blog.Core.Tasks\Blog.Core.Tasks.csproj", "{F8E9FA1F-4079-4F62-B717-E389BC0014E8}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Blog.Core.Extensions", "Blog.Core.Extensions\Blog.Core.Extensions.csproj", "{558F1B39-07E4-4FAB-BE7E-5B6104607064}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Blog.Core.ConsoleApp", "Blog.Core.ConsoleApp\Blog.Core.ConsoleApp.csproj", "{BB9FBBDF-B112-44F2-ABB7-9C31CFB619FE}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Blog.Core.AdminMvc", "Blog.Core.AdminMvc\Blog.Core.AdminMvc.csproj", "{06D885F3-6352-4BF6-B826-DEA742DFFBD7}"
-EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{D9833F24-7BD0-486F-B028-F1FD098AA1E1}"
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "SolutionItems", "SolutionItems", "{D9833F24-7BD0-486F-B028-F1FD098AA1E1}"
ProjectSection(SolutionItems) = preProject
.dockerignore = .dockerignore
.editorconfig = .editorconfig
@@ -44,7 +38,19 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{EDA8901E
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Blog.Core.Tests", "Blog.Core.Tests\Blog.Core.Tests.csproj", "{300A8113-8033-4184-BE28-FC48D8349CD0}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Blog.Core.EventBus", "Blog.Core.EventBus\Blog.Core.EventBus.csproj", "{E4D54281-8812-4C4D-AAE6-1365F172020B}"
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Gateways", "Gateways", "{E2BD7D4D-9ED5-41CD-8401-C3FB26F203BB}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Blog.Core.Gateway", "Blog.Core.Gateway\Blog.Core.Gateway.csproj", "{FC3D5C02-DED1-4A39-A8D9-A2EE1BE5A775}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Generators", "Generators", "{047A9723-9AAC-42E3-8C69-B3835F15FF96}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Blog.Core.FrameWork", "Blog.Core.FrameWork\Blog.Core.FrameWork.csproj", "{52D318A2-F44E-4CB7-8DD4-483357D4333F}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "EventBus", "EventBus", "{A592C96A-4E44-4F2A-AC21-30683AF6C493}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Blog.Core.EventBus", "Blog.Core.EventBus\Blog.Core.EventBus.csproj", "{17C9E9DC-E926-4C90-9025-3DAC55D7EDA3}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Blog.Core.ConsoleApp", "Blog.Core.ConsoleApp\Blog.Core.ConsoleApp.csproj", "{0B3265A9-6716-4D28-8648-C64D5E692ACA}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -76,10 +82,6 @@ Global
{97D32A49-994C-44C5-A167-51E71D173B6F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{97D32A49-994C-44C5-A167-51E71D173B6F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{97D32A49-994C-44C5-A167-51E71D173B6F}.Release|Any CPU.Build.0 = Release|Any CPU
- {44A2006E-3EFC-4179-B400-866178C66556}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {44A2006E-3EFC-4179-B400-866178C66556}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {44A2006E-3EFC-4179-B400-866178C66556}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {44A2006E-3EFC-4179-B400-866178C66556}.Release|Any CPU.Build.0 = Release|Any CPU
{F8E9FA1F-4079-4F62-B717-E389BC0014E8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F8E9FA1F-4079-4F62-B717-E389BC0014E8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F8E9FA1F-4079-4F62-B717-E389BC0014E8}.Release|Any CPU.ActiveCfg = Release|Any CPU
@@ -88,28 +90,36 @@ Global
{558F1B39-07E4-4FAB-BE7E-5B6104607064}.Debug|Any CPU.Build.0 = Debug|Any CPU
{558F1B39-07E4-4FAB-BE7E-5B6104607064}.Release|Any CPU.ActiveCfg = Release|Any CPU
{558F1B39-07E4-4FAB-BE7E-5B6104607064}.Release|Any CPU.Build.0 = Release|Any CPU
- {BB9FBBDF-B112-44F2-ABB7-9C31CFB619FE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {BB9FBBDF-B112-44F2-ABB7-9C31CFB619FE}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {BB9FBBDF-B112-44F2-ABB7-9C31CFB619FE}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {BB9FBBDF-B112-44F2-ABB7-9C31CFB619FE}.Release|Any CPU.Build.0 = Release|Any CPU
- {06D885F3-6352-4BF6-B826-DEA742DFFBD7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {06D885F3-6352-4BF6-B826-DEA742DFFBD7}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {06D885F3-6352-4BF6-B826-DEA742DFFBD7}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {06D885F3-6352-4BF6-B826-DEA742DFFBD7}.Release|Any CPU.Build.0 = Release|Any CPU
{300A8113-8033-4184-BE28-FC48D8349CD0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{300A8113-8033-4184-BE28-FC48D8349CD0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{300A8113-8033-4184-BE28-FC48D8349CD0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{300A8113-8033-4184-BE28-FC48D8349CD0}.Release|Any CPU.Build.0 = Release|Any CPU
- {E4D54281-8812-4C4D-AAE6-1365F172020B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {E4D54281-8812-4C4D-AAE6-1365F172020B}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {E4D54281-8812-4C4D-AAE6-1365F172020B}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {E4D54281-8812-4C4D-AAE6-1365F172020B}.Release|Any CPU.Build.0 = Release|Any CPU
+ {FC3D5C02-DED1-4A39-A8D9-A2EE1BE5A775}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {FC3D5C02-DED1-4A39-A8D9-A2EE1BE5A775}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {FC3D5C02-DED1-4A39-A8D9-A2EE1BE5A775}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {FC3D5C02-DED1-4A39-A8D9-A2EE1BE5A775}.Release|Any CPU.Build.0 = Release|Any CPU
+ {52D318A2-F44E-4CB7-8DD4-483357D4333F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {52D318A2-F44E-4CB7-8DD4-483357D4333F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {52D318A2-F44E-4CB7-8DD4-483357D4333F}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {52D318A2-F44E-4CB7-8DD4-483357D4333F}.Release|Any CPU.Build.0 = Release|Any CPU
+ {17C9E9DC-E926-4C90-9025-3DAC55D7EDA3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {17C9E9DC-E926-4C90-9025-3DAC55D7EDA3}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {17C9E9DC-E926-4C90-9025-3DAC55D7EDA3}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {17C9E9DC-E926-4C90-9025-3DAC55D7EDA3}.Release|Any CPU.Build.0 = Release|Any CPU
+ {0B3265A9-6716-4D28-8648-C64D5E692ACA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {0B3265A9-6716-4D28-8648-C64D5E692ACA}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {0B3265A9-6716-4D28-8648-C64D5E692ACA}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {0B3265A9-6716-4D28-8648-C64D5E692ACA}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{300A8113-8033-4184-BE28-FC48D8349CD0} = {EDA8901E-541E-4ADC-B71E-59697D5F9549}
+ {FC3D5C02-DED1-4A39-A8D9-A2EE1BE5A775} = {E2BD7D4D-9ED5-41CD-8401-C3FB26F203BB}
+ {52D318A2-F44E-4CB7-8DD4-483357D4333F} = {047A9723-9AAC-42E3-8C69-B3835F15FF96}
+ {17C9E9DC-E926-4C90-9025-3DAC55D7EDA3} = {A592C96A-4E44-4F2A-AC21-30683AF6C493}
+ {0B3265A9-6716-4D28-8648-C64D5E692ACA} = {047A9723-9AAC-42E3-8C69-B3835F15FF96}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {AB40D0C5-E3EA-4A9B-86C2-38F0BB33FC04}