增加Controller API模式

增加图片缓存API
This commit is contained in:
chfei committed 2026-09-14 15:48:11 +08:00
1 parent 8ee4bf59b9
commit e48ee01201
16 files changed
+906 -170

No files matched your search

@@ -0,0 +1,93 @@
using KJD_Web.Model;
using KJD_Web.Services;
using MySqlX.XDevAPI.Common;
using System;
using System.Collections.Generic;
using System.Web.Http;
using System.Web.Http.Results;
namespace KJD_Web.Controllers
{
[RoutePrefix("wxxd_ImageCache")]
[Route("{action}")]
public class ImageCacheController : ApiController
{
private readonly ImageCacheService _imageCacheService;
public ImageCacheController(ImageCacheService imageCacheService)
{
if (imageCacheService == null)
{
throw new ArgumentNullException("imageCacheService");
}
_imageCacheService = imageCacheService;
}
/// <summary>
/// 批量按 MD5 查询图片缓存。
/// </summary>
[HttpPost]
public IHttpActionResult GetImageCache([FromBody] ImageCacheBatchQueryRequest request)
{
List<ImageCacheEntity> data = new List<ImageCacheEntity>();
try
{
if (request != null && request.Md5s != null)
{
data = _imageCacheService.GetByMd5s(request.Md5s, request.Platform);
}
return Ok(ApiResult.Success(data));
}
catch (ArgumentException ex)
{
return Ok(ApiResult.Fail());
}
}
/// <summary>
/// 按 MD5 和平台更新平台图片 URL。
/// </summary>
[HttpPost]
public IHttpActionResult AddOrUpdate([FromBody] ImageCacheUpdateUrlRequest[] requests)
{
try
{
if (requests == null)
{
throw new Exception("参数错误");
}
foreach (var item in requests)
{
if (!_imageCacheService.AddOrUpdate(item.Md5, item.Platform, item.PlatformUrl))
{
throw new Exception("操作失败");
}
}
return Ok(ApiResult.Success(true));
}
catch (Exception ex)
{
return Ok(ApiResult.Fail(ex.Message));
}
}
}
public class ImageCacheBatchQueryRequest
{
public List<string> Md5s { get; set; }
public byte? Platform { get; set; }
}
public class ImageCacheUpdateUrlRequest
{
public string Md5 { get; set; }
public byte Platform { get; set; }
public string PlatformUrl { get; set; }
}
}
@@ -0,0 +1,54 @@
//using KJD_Web.BLL.WXXD;
//using System;
//using System.Collections.Generic;
//using System.IO;
//using System.Linq;
//using System.Runtime.Remoting.Contexts;
//using System.Text;
//using System.Web;
//using System.Web.Http;
//namespace KJD_Web.Controllers
//{
// [RoutePrefix("wxxd_user")]
// [Route("{action}")]
// public class WXUserController : ApiController
// {
// private string GetRequestJsonString()
// {
// //Context.Response.ContentType = "text/html;charset=utf-8";
// //Context.Response.ContentEncoding = System.Text.Encoding.GetEncoding("utf-8");
// using (Stream s = HttpContext.Current.Request.InputStream) // 获得json 字符流
// {
// // 还原数据流
// byte[] b = new byte[s.Length];
// s.Read(b, 0, (int)s.Length);
// string jsonText = Encoding.UTF8.GetString(b); // JSON字符串
// if (string.IsNullOrEmpty(jsonText))
// {
// var qs = HttpContext.Current.Request.QueryString;
// if (qs != null && qs.Keys.Count > 0)
// {
// jsonText = "{";
// foreach (var key in qs.Keys)
// {
// jsonText += "\"" + key + "\":" + "\"" + qs[key.ToString()] + "\";";
// }
// jsonText = jsonText.TrimEnd(';') + "}";
// }
// }
// return jsonText;
// }
// }
// public string user_login()
// {
// string jsontext = GetRequestJsonString();
// var result = jsontext;
// result = new WXUserManage().CheckUserLogin(jsontext);
// return result;
// }
// }
//}
@@ -0,0 +1,9 @@
namespace MAX.Core.DependencyInjection
{
/// <summary>
/// 作用域(每个 Scope/请求一个实例)
/// </summary>
public interface IScopedDependency
{
}
}
@@ -0,0 +1,9 @@
namespace MAX.Core.DependencyInjection
{
/// <summary>
/// 单例
/// </summary>
public interface ISingletonDependency
{
}
}
@@ -0,0 +1,9 @@
namespace MAX.Core.DependencyInjection
{
/// <summary>
/// 每次实例化
/// </summary>
public interface ITransientDependency
{
}
}
+237 -156
View File
@@ -1,165 +1,246 @@
using KJD_Web.Utils;
using Autofac;
using Autofac.Integration.WebApi;
using FreeSql;
using KJD_Web.Utils;
using MySql.Data.MySqlClient;
using MAX.Core.DependencyInjection;
using NLog;
using System;
using System.Configuration;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Web;
using System.Web.Http;
using System.Web.Security;
using System.Web.SessionState;
namespace KJD_Web
{
public class Global : System.Web.HttpApplication
{
public class Global : System.Web.HttpApplication
{
protected void Application_Start(object sender, EventArgs e)
{
LogHelper.Info("应用程序启动");
var container = BuildContainer();
// 让 Web API 用 Autofac 解析 Controller
GlobalConfiguration.Configuration.DependencyResolver =
new AutofacWebApiDependencyResolver(container);
GlobalConfiguration.Configure(WebApiConfig.Register);
}
protected void Session_Start(object sender, EventArgs e)
{
internal static IContainer BuildContainer()
{
var builder = new ContainerBuilder();
var appAssembly = Assembly.GetExecutingAssembly();
}
// ImageCacheService 使用独立的 imagecache 数据库。
builder.Register(_ => CreateImageCacheFreeSql())
.As<IFreeSql>()
.SingleInstance();
protected void Application_BeginRequest(object sender, EventArgs e)
{
string hPath = Request.Url.LocalPath.ToString();
if (!hPath.Contains(".asmx") && hPath.Contains("/user/"))
{
hPath = hPath.Replace("/user/", "/UserService.asmx/");
Context.RewritePath(hPath);
}
else if (!hPath.Contains(".asmx") && hPath.Contains("/shop/"))
{
hPath = hPath.Replace("/shop/", "/ShopService.asmx/");
Context.RewritePath(hPath);
}
else if (!hPath.Contains(".asmx") && hPath.Contains("/update/"))
{
hPath = hPath.Replace("/update/", "/UpdateService.asmx/");
Context.RewritePath(hPath);
}
else if (!hPath.Contains(".asmx") && hPath.Contains("/order/"))
{
hPath = hPath.Replace("/order/", "/OrderService.asmx/");
Context.RewritePath(hPath);
}
else if (!hPath.Contains(".asmx") && hPath.Contains("/product/"))
{
hPath = hPath.Replace("/product/", "/ProductService.asmx/");
Context.RewritePath(hPath);
}
else if (!hPath.Contains(".asmx") && hPath.Contains("/product_third/"))
{
hPath = hPath.Replace("/product_third/", "/ProductThirdService.asmx/");
Context.RewritePath(hPath);
}
else if (!hPath.Contains(".asmx") && hPath.Contains("/price/"))
{
hPath = hPath.Replace("/price/", "/PriceService.asmx/");
Context.RewritePath(hPath);
}
// 注册 Web API 所有 Controller
builder.RegisterApiControllers(appAssembly);
#region 注册所有IOC接口
Type typeSingleton = typeof(ISingletonDependency);
builder.RegisterAssemblyTypes(appAssembly)
.Where(a =>
typeSingleton.IsAssignableFrom(a)
&& a.IsClass
&& !a.IsAbstract
)
.AsImplementedInterfaces()
.AsSelf()
.SingleInstance();
Type typeTransient = typeof(ITransientDependency);
builder.RegisterAssemblyTypes(appAssembly)
.Where(a =>
typeTransient.IsAssignableFrom(a)
&& a.IsClass
&& !a.IsAbstract
)
.AsImplementedInterfaces()
.AsSelf()
.InstancePerDependency();
Type typeScoped = typeof(IScopedDependency);
builder.RegisterAssemblyTypes(appAssembly)
.Where(a => typeScoped.IsAssignableFrom(a) && a.IsClass && !a.IsAbstract)
.AsImplementedInterfaces()
.AsSelf()
.InstancePerRequest();
#endregion
return builder.Build();
}
private static IFreeSql CreateImageCacheFreeSql()
{
var connection = ConfigurationManager.ConnectionStrings["ConnKJD"];
if (connection == null || string.IsNullOrWhiteSpace(connection.ConnectionString))
{
throw new ConfigurationErrorsException("未配置连接字符串:ConnKJD");
}
var connectionBuilder = new MySqlConnectionStringBuilder(connection.ConnectionString)
{
Database = "imagecache"
};
return new FreeSqlBuilder()
.UseConnectionString(DataType.MySql, connectionBuilder.ConnectionString)
.UseAutoSyncStructure(false)
.Build();
}
protected void Session_Start(object sender, EventArgs e)
{
}
protected void Application_BeginRequest(object sender, EventArgs e)
{
string hPath = Request.Url.LocalPath.ToString();
if (!hPath.Contains(".asmx") && hPath.Contains("/user/"))
{
hPath = hPath.Replace("/user/", "/UserService.asmx/");
Context.RewritePath(hPath);
}
else if (!hPath.Contains(".asmx") && hPath.Contains("/shop/"))
{
hPath = hPath.Replace("/shop/", "/ShopService.asmx/");
Context.RewritePath(hPath);
}
else if (!hPath.Contains(".asmx") && hPath.Contains("/update/"))
{
hPath = hPath.Replace("/update/", "/UpdateService.asmx/");
Context.RewritePath(hPath);
}
else if (!hPath.Contains(".asmx") && hPath.Contains("/order/"))
{
hPath = hPath.Replace("/order/", "/OrderService.asmx/");
Context.RewritePath(hPath);
}
else if (!hPath.Contains(".asmx") && hPath.Contains("/product/"))
{
hPath = hPath.Replace("/product/", "/ProductService.asmx/");
Context.RewritePath(hPath);
}
else if (!hPath.Contains(".asmx") && hPath.Contains("/product_third/"))
{
hPath = hPath.Replace("/product_third/", "/ProductThirdService.asmx/");
Context.RewritePath(hPath);
}
else if (!hPath.Contains(".asmx") && hPath.Contains("/price/"))
{
hPath = hPath.Replace("/price/", "/PriceService.asmx/");
Context.RewritePath(hPath);
}
if (!hPath.Contains(".asmx") && hPath.Contains("/bxx_user/"))
{
hPath = hPath.Replace("/bxx_user/", "/BXXUserService.asmx/");
Context.RewritePath(hPath);
}
else if (!hPath.Contains(".asmx") && hPath.Contains("/bxx_shop/"))
{
hPath = hPath.Replace("/bxx_shop/", "/BXXShopService.asmx/");
Context.RewritePath(hPath);
}
//else if (!hPath.Contains(".asmx") && hPath.Contains("/update/"))
//{
// hPath = hPath.Replace("/update/", "/UpdateService.asmx/");
// Context.RewritePath(hPath);
//}
else if (!hPath.Contains(".asmx") && hPath.Contains("/bxx_product/"))
{
hPath = hPath.Replace("/bxx_product/", "/BXXProductService.asmx/");
Context.RewritePath(hPath);
}
else if (!hPath.Contains(".asmx") && hPath.Contains("/bxx_product_third/"))
{
hPath = hPath.Replace("/bxx_product_third/", "/BXXProductThirdService.asmx/");
Context.RewritePath(hPath);
}
else if (!hPath.Contains(".asmx") && hPath.Contains("/bxx_price/"))
{
hPath = hPath.Replace("/bxx_price/", "/BXXPriceService.asmx/");
Context.RewritePath(hPath);
}
if (!hPath.Contains(".asmx") && hPath.Contains("/bxx_user/"))
{
hPath = hPath.Replace("/bxx_user/", "/BXXUserService.asmx/");
Context.RewritePath(hPath);
}
else if (!hPath.Contains(".asmx") && hPath.Contains("/bxx_shop/"))
{
hPath = hPath.Replace("/bxx_shop/", "/BXXShopService.asmx/");
Context.RewritePath(hPath);
}
//else if (!hPath.Contains(".asmx") && hPath.Contains("/update/"))
//{
// hPath = hPath.Replace("/update/", "/UpdateService.asmx/");
// Context.RewritePath(hPath);
//}
else if (!hPath.Contains(".asmx") && hPath.Contains("/bxx_product/"))
{
hPath = hPath.Replace("/bxx_product/", "/BXXProductService.asmx/");
Context.RewritePath(hPath);
}
else if (!hPath.Contains(".asmx") && hPath.Contains("/bxx_product_third/"))
{
hPath = hPath.Replace("/bxx_product_third/", "/BXXProductThirdService.asmx/");
Context.RewritePath(hPath);
}
else if (!hPath.Contains(".asmx") && hPath.Contains("/bxx_price/"))
{
hPath = hPath.Replace("/bxx_price/", "/BXXPriceService.asmx/");
Context.RewritePath(hPath);
}
if (!hPath.Contains(".asmx") && hPath.Contains("/dyxd_user/"))
{
hPath = hPath.Replace("/dyxd_user/", "/DYUserService.asmx/");
Context.RewritePath(hPath);
}
else if (!hPath.Contains(".asmx") && hPath.Contains("/dyxd_shop/"))
{
hPath = hPath.Replace("/dyxd_shop/", "/DYShopService.asmx/");
Context.RewritePath(hPath);
}
//else if (!hPath.Contains(".asmx") && hPath.Contains("/update/"))
//{
// hPath = hPath.Replace("/update/", "/UpdateService.asmx/");
// Context.RewritePath(hPath);
//}
else if (!hPath.Contains(".asmx") && hPath.Contains("/dyxd_product/"))
{
hPath = hPath.Replace("/dyxd_product/", "/DYProductService.asmx/");
Context.RewritePath(hPath);
}
else if (!hPath.Contains(".asmx") && hPath.Contains("/dyxd_product_third/"))
{
hPath = hPath.Replace("/dyxd_product_third/", "/DYProductThirdService.asmx/");
Context.RewritePath(hPath);
}
else if (!hPath.Contains(".asmx") && hPath.Contains("/dyxd_price/"))
{
hPath = hPath.Replace("/dyxd_price/", "/DYPriceService.asmx/");
Context.RewritePath(hPath);
}
if (!hPath.Contains(".asmx") && hPath.Contains("/dyxd_user/"))
{
hPath = hPath.Replace("/dyxd_user/", "/DYUserService.asmx/");
Context.RewritePath(hPath);
}
else if (!hPath.Contains(".asmx") && hPath.Contains("/dyxd_shop/"))
{
hPath = hPath.Replace("/dyxd_shop/", "/DYShopService.asmx/");
Context.RewritePath(hPath);
}
//else if (!hPath.Contains(".asmx") && hPath.Contains("/update/"))
//{
// hPath = hPath.Replace("/update/", "/UpdateService.asmx/");
// Context.RewritePath(hPath);
//}
else if (!hPath.Contains(".asmx") && hPath.Contains("/dyxd_product/"))
{
hPath = hPath.Replace("/dyxd_product/", "/DYProductService.asmx/");
Context.RewritePath(hPath);
}
else if (!hPath.Contains(".asmx") && hPath.Contains("/dyxd_product_third/"))
{
hPath = hPath.Replace("/dyxd_product_third/", "/DYProductThirdService.asmx/");
Context.RewritePath(hPath);
}
else if (!hPath.Contains(".asmx") && hPath.Contains("/dyxd_price/"))
{
hPath = hPath.Replace("/dyxd_price/", "/DYPriceService.asmx/");
Context.RewritePath(hPath);
}
if (!hPath.Contains(".asmx") && hPath.Contains("/wxxd_user/"))
{
hPath = hPath.Replace("/wxxd_user/", "/WXUserService.asmx/");
Context.RewritePath(hPath);
}
else if (!hPath.Contains(".asmx") && hPath.Contains("/wxxd_shop/"))
{
hPath = hPath.Replace("/wxxd_shop/", "/WXShopService.asmx/");
Context.RewritePath(hPath);
}
//else if (!hPath.Contains(".asmx") && hPath.Contains("/update/"))
//{
// hPath = hPath.Replace("/update/", "/UpdateService.asmx/");
// Context.RewritePath(hPath);
//}
else if (!hPath.Contains(".asmx") && hPath.Contains("/wxxd_product/"))
{
hPath = hPath.Replace("/wxxd_product/", "/WXProductService.asmx/");
Context.RewritePath(hPath);
}
else if (!hPath.Contains(".asmx") && hPath.Contains("/wxxd_product_third/"))
{
hPath = hPath.Replace("/wxxd_product_third/", "/WXProductThirdService.asmx/");
Context.RewritePath(hPath);
}
else if (!hPath.Contains(".asmx") && hPath.Contains("/wxxd_price/"))
{
hPath = hPath.Replace("/wxxd_price/", "/WXPriceService.asmx/");
Context.RewritePath(hPath);
}
else if (!hPath.Contains(".asmx") && hPath.Contains("/wxxd_order/"))
{
hPath = hPath.Replace("/wxxd_order/", "/WXOrderService.asmx/");
Context.RewritePath(hPath);
if (!hPath.Contains(".asmx") && hPath.Contains("/wxxd_user/"))
{
hPath = hPath.Replace("/wxxd_user/", "/WXUserService.asmx/");
Context.RewritePath(hPath, false);
}
else if (!hPath.Contains(".asmx") && hPath.Contains("/wxxd_shop/"))
{
hPath = hPath.Replace("/wxxd_shop/", "/WXShopService.asmx/");
Context.RewritePath(hPath);
}
//else if (!hPath.Contains(".asmx") && hPath.Contains("/update/"))
//{
// hPath = hPath.Replace("/update/", "/UpdateService.asmx/");
// Context.RewritePath(hPath);
//}
else if (!hPath.Contains(".asmx") && hPath.Contains("/wxxd_product/"))
{
hPath = hPath.Replace("/wxxd_product/", "/WXProductService.asmx/");
Context.RewritePath(hPath);
}
else if (!hPath.Contains(".asmx") && hPath.Contains("/wxxd_product_third/"))
{
hPath = hPath.Replace("/wxxd_product_third/", "/WXProductThirdService.asmx/");
Context.RewritePath(hPath);
}
else if (!hPath.Contains(".asmx") && hPath.Contains("/wxxd_price/"))
{
hPath = hPath.Replace("/wxxd_price/", "/WXPriceService.asmx/");
Context.RewritePath(hPath);
}
else if (!hPath.Contains(".asmx") && hPath.Contains("/wxxd_order/"))
{
hPath = hPath.Replace("/wxxd_order/", "/WXOrderService.asmx/");
Context.RewritePath(hPath);
}
else if (!hPath.Contains(".asmx") && hPath.Contains("/wxxd_shop_revenue_statistics/"))
{
@@ -170,30 +251,30 @@ namespace KJD_Web
//try { ApiRequestLogger.BeginRequest(Context); } catch { }
}
protected void Application_AuthenticateRequest(object sender, EventArgs e)
{
protected void Application_AuthenticateRequest(object sender, EventArgs e)
{
}
}
protected void Application_EndRequest(object sender, EventArgs e)
{
// 请求录制:合并响应内容并落盘
//try { ApiRequestLogger.EndRequest(Context); } catch { }
}
protected void Application_EndRequest(object sender, EventArgs e)
{
// 请求录制:合并响应内容并落盘
//try { ApiRequestLogger.EndRequest(Context); } catch { }
}
protected void Application_Error(object sender, EventArgs e)
{
protected void Application_Error(object sender, EventArgs e)
{
}
}
protected void Session_End(object sender, EventArgs e)
{
protected void Session_End(object sender, EventArgs e)
{
}
}
protected void Application_End(object sender, EventArgs e)
{
protected void Application_End(object sender, EventArgs e)
{
}
}
}
}
}
+85 -6
View File
@@ -13,7 +13,7 @@
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>KJD_Web</RootNamespace>
<AssemblyName>KJD_WebService</AssemblyName>
<TargetFrameworkVersion>v4.6.2</TargetFrameworkVersion>
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<UseIISExpress>true</UseIISExpress>
<Use64BitIISExpress />
<IISExpressSSLPort>44313</IISExpressSSLPort>
@@ -46,22 +46,80 @@
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<ItemGroup>
<Reference Include="Autofac, Version=9.3.2.0, Culture=neutral, PublicKeyToken=17863af14b0044da, processorArchitecture=MSIL">
<HintPath>..\packages\Autofac.9.3.2\lib\netstandard2.0\Autofac.dll</HintPath>
</Reference>
<Reference Include="Autofac.Integration.WebApi, Version=6.2.0.0, Culture=neutral, PublicKeyToken=17863af14b0044da, processorArchitecture=MSIL">
<HintPath>..\packages\Autofac.WebApi2.6.2.0\lib\net472\Autofac.Integration.WebApi.dll</HintPath>
</Reference>
<Reference Include="BouncyCastle.Crypto, Version=1.9.0.0, Culture=neutral, PublicKeyToken=0e99375e54769942, processorArchitecture=MSIL">
<HintPath>..\packages\Portable.BouncyCastle.1.9.0\lib\net40\BouncyCastle.Crypto.dll</HintPath>
</Reference>
<Reference Include="FreeSql, Version=3.5.311.0, Culture=neutral, PublicKeyToken=a33928e5d4a4b39c, processorArchitecture=MSIL">
<HintPath>..\packages\FreeSql.3.5.311\lib\net451\FreeSql.dll</HintPath>
</Reference>
<Reference Include="FreeSql.Provider.MySql, Version=3.5.311.0, Culture=neutral, PublicKeyToken=09c4767ab6141ff5, processorArchitecture=MSIL">
<HintPath>..\packages\FreeSql.Provider.MySql.3.5.311\lib\net452\FreeSql.Provider.MySql.dll</HintPath>
</Reference>
<Reference Include="Google.Protobuf, Version=3.19.4.0, Culture=neutral, PublicKeyToken=a7d26565bac4d604, processorArchitecture=MSIL">
<HintPath>..\packages\Google.Protobuf.3.19.4\lib\net45\Google.Protobuf.dll</HintPath>
</Reference>
<Reference Include="K4os.Compression.LZ4, Version=1.2.6.0, Culture=neutral, PublicKeyToken=2186fa9121ef231d, processorArchitecture=MSIL">
<HintPath>..\packages\K4os.Compression.LZ4.1.2.6\lib\net46\K4os.Compression.LZ4.dll</HintPath>
</Reference>
<Reference Include="K4os.Compression.LZ4.Streams, Version=1.2.6.0, Culture=neutral, PublicKeyToken=2186fa9121ef231d, processorArchitecture=MSIL">
<HintPath>..\packages\K4os.Compression.LZ4.Streams.1.2.6\lib\net46\K4os.Compression.LZ4.Streams.dll</HintPath>
</Reference>
<Reference Include="K4os.Hash.xxHash, Version=1.0.6.0, Culture=neutral, PublicKeyToken=32cd54395057cec3, processorArchitecture=MSIL">
<HintPath>..\packages\K4os.Hash.xxHash.1.0.6\lib\net46\K4os.Hash.xxHash.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Bcl.AsyncInterfaces, Version=10.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Bcl.AsyncInterfaces.10.0.0\lib\net462\Microsoft.Bcl.AsyncInterfaces.dll</HintPath>
</Reference>
<Reference Include="Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=2.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.2.0.1\lib\net45\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.dll</HintPath>
</Reference>
<Reference Include="Microsoft.CSharp" />
<Reference Include="MySql.Data">
<HintPath>..\Dll\MySql.Data.dll</HintPath>
<Reference Include="MySql.Data, Version=8.0.30.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d, processorArchitecture=MSIL">
<HintPath>..\packages\MySql.Data.8.0.30\lib\net452\MySql.Data.dll</HintPath>
</Reference>
<Reference Include="Newtonsoft.Json, Version=13.0.1.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\Dll\Newtonsoft.Json.dll</HintPath>
<Reference Include="Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\packages\Newtonsoft.Json.13.0.4\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="Newtonsoft.Json.Bson, Version=1.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\packages\Newtonsoft.Json.Bson.1.0.2\lib\net45\Newtonsoft.Json.Bson.dll</HintPath>
</Reference>
<Reference Include="NLog, Version=6.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
<HintPath>..\packages\NLog.6.2.0\lib\net46\NLog.dll</HintPath>
</Reference>
<Reference Include="System.Buffers, Version=4.0.5.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Buffers.4.6.1\lib\net462\System.Buffers.dll</HintPath>
</Reference>
<Reference Include="System.ComponentModel" />
<Reference Include="System.Configuration.Install" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="System.Diagnostics.DiagnosticSource, Version=10.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Diagnostics.DiagnosticSource.10.0.0\lib\net462\System.Diagnostics.DiagnosticSource.dll</HintPath>
</Reference>
<Reference Include="System.Management" />
<Reference Include="System.Memory, Version=4.0.5.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Memory.4.6.3\lib\net462\System.Memory.dll</HintPath>
</Reference>
<Reference Include="System.Net.Http" />
<Reference Include="System.Net.Http.Formatting, Version=6.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.WebApi.Client.6.0.0\lib\net45\System.Net.Http.Formatting.dll</HintPath>
</Reference>
<Reference Include="System.Numerics" />
<Reference Include="System.Numerics.Vectors, Version=4.1.6.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Numerics.Vectors.4.6.1\lib\net462\System.Numerics.Vectors.dll</HintPath>
</Reference>
<Reference Include="System.Runtime.CompilerServices.Unsafe, Version=6.0.3.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Runtime.CompilerServices.Unsafe.6.1.2\lib\net462\System.Runtime.CompilerServices.Unsafe.dll</HintPath>
</Reference>
<Reference Include="System.Threading.Tasks.Extensions, Version=4.2.4.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Threading.Tasks.Extensions.4.6.3\lib\net462\System.Threading.Tasks.Extensions.dll</HintPath>
</Reference>
<Reference Include="System.Transactions" />
<Reference Include="System.Web.DynamicData" />
<Reference Include="System.Web.Entity" />
<Reference Include="System.Web.ApplicationServices" />
@@ -71,11 +129,23 @@
<Reference Include="System.Drawing" />
<Reference Include="System.Web" />
<Reference Include="System.Web.Extensions" />
<Reference Include="System.Web.Http, Version=5.3.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.WebApi.Core.5.3.0\lib\net45\System.Web.Http.dll</HintPath>
</Reference>
<Reference Include="System.Web.Http.WebHost, Version=5.3.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.WebApi.WebHost.5.3.0\lib\net45\System.Web.Http.WebHost.dll</HintPath>
</Reference>
<Reference Include="System.Xml" />
<Reference Include="System.Configuration" />
<Reference Include="System.Web.Services" />
<Reference Include="System.EnterpriseServices" />
<Reference Include="System.Xml.Linq" />
<Reference Include="Ubiety.Dns.Core, Version=2.2.1.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d, processorArchitecture=MSIL">
<HintPath>..\packages\MySql.Data.8.0.30\lib\net452\Ubiety.Dns.Core.dll</HintPath>
</Reference>
<Reference Include="ZstdNet, Version=1.4.5.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d, processorArchitecture=MSIL">
<HintPath>..\packages\MySql.Data.8.0.30\lib\net452\ZstdNet.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Content Include="WXOrderService.asmx" />
@@ -132,7 +202,13 @@
<Compile Include="BLL\WXXD\WXShopManage.cs" />
<Compile Include="BLL\WXXD\WXShopRevenueStatisticsManage.cs" />
<Compile Include="BLL\WXXD\WXUserManage.cs" />
<Compile Include="Controllers\ImageCacheController.cs" />
<Compile Include="Controllers\WXUserController.cs" />
<Compile Include="DependencyInjection\IScopedDependency.cs" />
<Compile Include="DependencyInjection\ISingletonDependency.cs" />
<Compile Include="DependencyInjection\ITransientDependency.cs" />
<Compile Include="LogHelper.cs" />
<Compile Include="Model\ApiResult.cs" />
<Compile Include="Model\ErpModel\ErpMerchantInfo.cs" />
<Compile Include="Model\JSTDownProdSkuInfo.cs" />
<Compile Include="Model\PddModel\BuyerLoginInfo.cs" />
@@ -168,7 +244,10 @@
<Compile Include="Model\WxModel\wx_qualification_image_info.cs" />
<Compile Include="Model\WxProdSecretSpuIdShopIdMapParam.cs" />
<Compile Include="Model\WXShopDefaultAddressInfo.cs" />
<Compile Include="NotFoundMessageFilter.cs" />
<Compile Include="Services\ImageCacheService.cs" />
<Compile Include="Utils\ApiRequestLogger.cs" />
<Compile Include="WebApiConfig.cs" />
<Compile Include="WXOrderService.asmx.cs">
<DependentUpon>WXOrderService.asmx</DependentUpon>
<SubType>Component</SubType>
+68
View File
@@ -0,0 +1,68 @@
namespace KJD_Web.Model
{
public static class ResultCode
{
public const int Success = 200;
public const int Fail = 500;
public const int Unauthorized = 401;
public const int Forbidden = 403;
public const int NotFound = 404;
/// <summary>
/// 参数校验失败
/// </summary>
public const int ValidationError = 1001;
/// <summary>
/// 业务逻辑异常
/// </summary>
public const int BusinessError = 2001;
/// <summary>
/// 服务器内部错误
/// </summary>
public const int ServerError = 5000;
}
/// <summary>
/// 非泛型基类,用于统一处理
/// </summary>
public abstract class ApiResultBase
{
/// <summary>业务状态码</summary>
public int Code { get; set; } = ResultCode.Success;
/// <summary>提示信息</summary>
public string Msg { get; set; }
/// <summary>请求是否成功</summary>
public bool IsSuccess => Code == ResultCode.Success;
}
/// <summary>
/// 泛型响应
/// </summary>
public class ApiResult<T> : ApiResultBase
{
public T Data { get; set; }
public static ApiResult<T> Success(T data, string msg = "操作成功")
=> new ApiResult<T> { Code = ResultCode.Success, Data = data, Msg = msg };
public static ApiResult<T> Fail(string msg = "操作失败", int code = ResultCode.Fail, T data = default)
=> new ApiResult<T> { Code = code, Msg = msg, Data = data };
}
/// <summary>
/// 无数据响应(等同于 ApiResult<object>)
/// </summary>
public class ApiResult : ApiResult<object>
{
public static ApiResult Success(string msg = "操作成功")
=> new ApiResult { Code = ResultCode.Success, Msg = msg };
public static ApiResult Fail(string msg = "操作失败", int code = ResultCode.Fail)
=> new ApiResult { Code = code, Msg = msg };
}
}
+49
View File
@@ -0,0 +1,49 @@
using KJD_Web.Model;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Web;
using System.Web.Http.Filters;
namespace KJD_Web
{
public class NotFoundMessageFilter : ActionFilterAttribute
{
public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
{
if (actionExecutedContext.Response != null &&
actionExecutedContext.Response.StatusCode == HttpStatusCode.NotFound)
{
actionExecutedContext.Response = actionExecutedContext.Request.CreateResponse(
HttpStatusCode.NotFound, ApiResult.Fail("请求失败", ResultCode.NotFound));
}
}
}
public class NotFoundMessageHandler : DelegatingHandler
{
protected override async Task<HttpResponseMessage> SendAsync(
HttpRequestMessage request, CancellationToken cancellationToken)
{
var response = await base.SendAsync(request, cancellationToken);
if (response.StatusCode != HttpStatusCode.OK)
{
response.Content = new StringContent(
JsonConvert.SerializeObject(ApiResult.Fail("请求失败", ResultCode.NotFound)),
Encoding.UTF8,
"application/json");
}
return response;
}
}
}
@@ -2,6 +2,8 @@
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
[assembly: InternalsVisibleTo("WebServiceTest")]
// 有关程序集的常规信息通过下列特性集
// 控制。更改这些特性值可修改
// 与程序集关联的信息。
@@ -0,0 +1,194 @@
using FreeSql;
using FreeSql.DataAnnotations;
using MAX.Core.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Linq;
namespace KJD_Web.Services
{
[Table(Name = "images_0")]
public class ImageCacheEntity
{
[Column(Name = "id", IsIdentity = true, IsPrimary = true)]
public long id { get; set; }
[Column(Name = "platform")]
public byte platform { get; set; }
[Column(Name = "source_url_md5", StringLength = 32)]
public string source_url_md5 { get; set; }
[Column(Name = "platform_url", StringLength = 1000)]
public string platform_url { get; set; }
[Column(Name = "create_time")]
public DateTime create_time { get; set; }
[Column(Name = "update_time")]
public DateTime update_time { get; set; }
}
public class ImageCacheService : ISingletonDependency
{
private const int Md5Length = 32;
private const int PlatformUrlMaxLength = 1000;
private readonly IFreeSql _freeSql;
public ImageCacheService(IFreeSql freeSql)
{
if (freeSql == null)
{
throw new ArgumentNullException("freeSql");
}
_freeSql = freeSql;
}
/// <summary>
/// 按 MD5 查询图片缓存;platform 为空时返回该 MD5 在所有平台的缓存。
/// </summary>
public ImageCacheEntity GetByMd5(string sourceUrlMd5, byte? platform = null)
{
var md5 = NormalizeMd5(sourceUrlMd5);
return GetByMd5sInternal(new List<string> { md5 }, platform).FirstOrDefault();
}
/// <summary>
/// 批量按 MD5 查询图片缓存。MD5 会按首字符分组,只查询对应的 images_0 到 images_f 分表。
/// </summary>
public List<ImageCacheEntity> GetByMd5s(IEnumerable<string> sourceUrlMd5s, byte? platform = null)
{
return GetByMd5sInternal(NormalizeMd5s(sourceUrlMd5s), platform);
}
/// <summary>
/// 按 MD5 和平台直接修改平台图片 URL,未找到时返回 false。
/// </summary>
public bool AddOrUpdate(string sourceUrlMd5, byte platform, string platformUrl)
{
var md5 = NormalizeMd5(sourceUrlMd5);
ValidatePlatformUrl(platformUrl);
var tableName = GetTableName(md5[0]);
var existing = _freeSql.Select<ImageCacheEntity>()
.AsTable((type, oldName) => tableName)
.Where(a => a.source_url_md5 == sourceUrlMd5 && a.platform == platform)
.First();
var now = DateTime.Now;
if (existing != null)
{
var affected = _freeSql.Update<ImageCacheEntity>()
.AsTable(tableName)
.Set(a => a.platform_url, platformUrl)
.Set(a => a.update_time, now)
.Where(a => a.source_url_md5 == md5 && a.platform == platform)
.ExecuteAffrows();
return affected > 0;
}
else
{
ImageCacheEntity imageCache = new ImageCacheEntity();
imageCache.id = 0;
imageCache.source_url_md5 = md5;
imageCache.platform = platform;
imageCache.platform_url = platformUrl;
imageCache.create_time = now;
imageCache.update_time = now;
imageCache.id = _freeSql.Insert(imageCache)
.AsTable(tableName)
.ExecuteIdentity();
return imageCache.id > 0;
}
}
private List<ImageCacheEntity> GetByMd5sInternal(List<string> md5s, byte? platform)
{
var result = new List<ImageCacheEntity>();
if (md5s.Count == 0)
{
return result;
}
foreach (var shard in md5s.GroupBy(a => a[0]))
{
var tableName = GetTableName(shard.Key);
var md5sInTable = shard.ToList();
var query = _freeSql.Select<ImageCacheEntity>()
.AsTable((type, oldName) => tableName)
.Where(a => md5sInTable.Contains(a.source_url_md5));
if (platform.HasValue)
{
var platformValue = platform.Value;
query = query.Where(a => a.platform == platformValue);
}
result.AddRange(query.ToList());
}
return result;
}
private List<string> NormalizeMd5s(IEnumerable<string> sourceUrlMd5s)
{
if (sourceUrlMd5s == null)
{
throw new ArgumentNullException("sourceUrlMd5s");
}
var result = new List<string>();
foreach (var sourceUrlMd5 in sourceUrlMd5s)
{
var md5 = NormalizeMd5(sourceUrlMd5);
if (!result.Contains(md5))
{
result.Add(md5);
}
}
return result;
}
private string NormalizeMd5(string sourceUrlMd5)
{
if (string.IsNullOrWhiteSpace(sourceUrlMd5))
{
throw new ArgumentException("MD5 不能为空", "sourceUrlMd5");
}
var md5 = sourceUrlMd5.Trim().ToLowerInvariant();
if (md5.Length != Md5Length || md5.Any(a => !Uri.IsHexDigit(a)))
{
throw new ArgumentException("MD5 必须是 32 位十六进制字符串", "sourceUrlMd5");
}
return md5;
}
private string GetTableName(char shard)
{
return "images_" + shard;
}
private void ValidatePlatformUrl(string platformUrl)
{
if (string.IsNullOrWhiteSpace(platformUrl))
{
throw new ArgumentException("平台图片 URL 不能为空", "platformUrl");
}
if (platformUrl.Length > PlatformUrlMaxLength)
{
throw new ArgumentException("平台图片 URL 长度不能超过 1000", "platformUrl");
}
}
}
}
+28
View File
@@ -0,0 +1,28 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Http;
namespace KJD_Web
{
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// 特性路由:你 ImageCacheController 上的 [Route] 依赖这个
config.MapHttpAttributeRoutes();
// 默认路由
//config.Routes.MapHttpRoute(
// name: "DefaultApi",
// routeTemplate: "{controller}/{action}/{id}",
// defaults: new { id = RouteParameter.Optional }
//);
//config.Formatters.Remove(config.Formatters.XmlFormatter);
//config.Filters.Add(new NotFoundMessageFilter());
//config.MessageHandlers.Add(new NotFoundMessageHandler());
}
}
}
+26
View File
@@ -1,5 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Autofac" version="9.3.2" targetFramework="net462" />
<package id="Autofac.WebApi2" version="6.2.0" targetFramework="net472" />
<package id="FreeSql" version="3.5.311" targetFramework="net472" />
<package id="FreeSql.Provider.MySql" version="3.5.311" targetFramework="net472" />
<package id="Google.Protobuf" version="3.19.4" targetFramework="net472" />
<package id="K4os.Compression.LZ4" version="1.2.6" targetFramework="net472" />
<package id="K4os.Compression.LZ4.Streams" version="1.2.6" targetFramework="net472" />
<package id="K4os.Hash.xxHash" version="1.0.6" targetFramework="net472" />
<package id="Microsoft.AspNet.WebApi" version="5.3.0" targetFramework="net472" />
<package id="Microsoft.AspNet.WebApi.Client" version="6.0.0" targetFramework="net472" />
<package id="Microsoft.AspNet.WebApi.Client.zh-Hans" version="6.0.0" targetFramework="net472" />
<package id="Microsoft.AspNet.WebApi.Core" version="5.3.0" targetFramework="net472" />
<package id="Microsoft.AspNet.WebApi.Core.zh-Hans" version="5.3.0" targetFramework="net472" />
<package id="Microsoft.AspNet.WebApi.WebHost" version="5.3.0" targetFramework="net472" />
<package id="Microsoft.AspNet.WebApi.WebHost.zh-Hans" version="5.3.0" targetFramework="net472" />
<package id="Microsoft.Bcl.AsyncInterfaces" version="10.0.0" targetFramework="net462" />
<package id="Microsoft.CodeDom.Providers.DotNetCompilerPlatform" version="2.0.1" targetFramework="net46" />
<package id="MySql.Data" version="8.0.30" targetFramework="net472" />
<package id="Newtonsoft.Json" version="13.0.4" targetFramework="net472" />
<package id="Newtonsoft.Json.Bson" version="1.0.2" targetFramework="net472" />
<package id="NLog" version="6.2.0" targetFramework="net462" />
<package id="Portable.BouncyCastle" version="1.9.0" targetFramework="net472" />
<package id="System.Buffers" version="4.6.1" targetFramework="net462" />
<package id="System.Diagnostics.DiagnosticSource" version="10.0.0" targetFramework="net462" />
<package id="System.Memory" version="4.6.3" targetFramework="net462" />
<package id="System.Numerics.Vectors" version="4.6.1" targetFramework="net462" />
<package id="System.Runtime.CompilerServices.Unsafe" version="6.1.2" targetFramework="net462" />
<package id="System.Threading.Tasks.Extensions" version="4.6.3" targetFramework="net462" />
</packages>
+6 -6
View File
@@ -5,10 +5,10 @@
-->
<configuration>
<connectionStrings>
<add name="ConnKJD" connectionString="Max Pool Size=512;Database='kjd';Data Source='nj-cynosdbmysql-grp-hl51pkfr.sql.tencentcdb.com';Port=27660;User Id='kjd';Password='Temukjd0625';Charset=utf8mb4;"/>
<!--<add name="ConnKJD" connectionString="Max Pool Size=512;Database='kjd';Data Source='nj-cynosdbmysql-grp-hl51pkfr.sql.tencentcdb.com';Port=27660;User Id='kjd';Password='Temukjd0625';Charset=utf8mb4;"/>-->
<add name="ConnKJD" connectionString="Server=192.168.0.200;Port=3306;Database=mysql;Uid=root;Pwd=123456;"/>
<!--<add name="ConnKJD" connectionString="Server=localhost;Port=3306;Database=mysql;Uid=root;Pwd=123456;"/>-->
<add name="ConnKJDBAK" connectionString="Max Pool Size=512;Database='kjd';Data Source='nj-cynosdbmysql-grp-9s7x16mt.sql.tencentcdb.com';Port=24049;User Id='kjdbak';Password='Temukjd0126';Charset=utf8mb4;"/>
<add name="UpdateVersion" connectionString="525"/>
<add name="UpdateFileDir" connectionString="C:\inetpub\wwwroot\kjd_update"/>
@@ -37,9 +37,9 @@
</system.Web>
-->
<system.web>
<compilation debug="true" targetFramework="4.6.2"/>
<compilation debug="true" targetFramework="4.7.2"/>
<!--<customErrors mode="Off"/>-->
<httpRuntime targetFramework="4.5.2" requestValidationMode="2.0"/>
<httpRuntime targetFramework="4.7.2" requestValidationMode="2.0"/>
<webServices>
<protocols>
<add name="HttpGet"/>
@@ -55,7 +55,7 @@
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral"/>
<bindingRedirect oldVersion="0.0.0.0-12.0.0.0" newVersion="9.0.0.0"/>
<bindingRedirect oldVersion="0.0.0.0-13.0.0.0" newVersion="13.0.0.0"/>
</dependentAssembly>
</assemblyBinding>
</runtime>
+1 -1
View File
@@ -25,7 +25,7 @@ namespace WebServiceTest
});
Console.WriteLine(ret);
}
catch (Exception ex)
catch (Exception)
{
}
+36 -1
View File
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net462</TargetFramework>
<TargetFramework>net472</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<LangVersion>12</LangVersion>
@@ -22,7 +22,42 @@
</ItemGroup>
<ItemGroup>
<Reference Include="Autofac">
<HintPath>..\..\packages\Autofac.9.3.2\lib\netstandard2.0\Autofac.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Bcl.AsyncInterfaces">
<HintPath>..\..\packages\Microsoft.Bcl.AsyncInterfaces.10.0.0\lib\net462\Microsoft.Bcl.AsyncInterfaces.dll</HintPath>
</Reference>
<Reference Include="System.Buffers">
<HintPath>..\..\packages\System.Buffers.4.6.1\lib\net462\System.Buffers.dll</HintPath>
</Reference>
<Reference Include="System.Diagnostics.DiagnosticSource">
<HintPath>..\..\packages\System.Diagnostics.DiagnosticSource.10.0.0\lib\net462\System.Diagnostics.DiagnosticSource.dll</HintPath>
</Reference>
<Reference Include="System.Memory">
<HintPath>..\..\packages\System.Memory.4.6.3\lib\net462\System.Memory.dll</HintPath>
</Reference>
<Reference Include="System.Runtime.CompilerServices.Unsafe">
<HintPath>..\..\packages\System.Runtime.CompilerServices.Unsafe.6.1.2\lib\net462\System.Runtime.CompilerServices.Unsafe.dll</HintPath>
</Reference>
<Reference Include="System.Threading.Tasks.Extensions">
<HintPath>..\..\packages\System.Threading.Tasks.Extensions.4.6.3\lib\net462\System.Threading.Tasks.Extensions.dll</HintPath>
</Reference>
<Reference Include="FreeSql">
<HintPath>..\..\packages\FreeSql.3.5.311\lib\net451\FreeSql.dll</HintPath>
</Reference>
<Reference Include="FreeSql.Provider.MySql">
<HintPath>..\..\packages\FreeSql.Provider.MySql.3.5.311\lib\net452\FreeSql.Provider.MySql.dll</HintPath>
</Reference>
<Reference Include="MySql.Data">
<HintPath>..\..\packages\MySql.Data.8.0.30\lib\net452\MySql.Data.dll</HintPath>
</Reference>
<Reference Include="System.Configuration" />
<Reference Include="System.Web" />
<Reference Include="System.Web.Http">
<HintPath>..\..\packages\Microsoft.AspNet.WebApi.Core.5.3.0\lib\net45\System.Web.Http.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>