From 5b47958807fba6e0b3b4d8957ab60b46bd786b3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BF=97=E9=93=AD=20=E5=90=95?= <896951544@qq.com> Date: Wed, 19 Mar 2025 14:06:46 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9WCS=E6=8F=90=E4=BE=9B?= =?UTF-8?q?=E7=9A=84=E6=8E=A5=E5=8F=A3=E4=BB=A3=E7=A0=81(=E4=BB=BB?= =?UTF-8?q?=E5=8A=A1=E4=B8=8B=E5=8F=91=EF=BC=8C=E5=8F=96=E6=B6=88=E4=BB=BB?= =?UTF-8?q?=E5=8A=A1)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SDWebApi/App_Start/SwaggerConfig.cs | 255 ++++++++++++ SDWebApi/App_Start/WebApiConfig.cs | 24 ++ SDWebApi/Controllers/thirdParty.cs | 365 ++++++++++++++++++ SDWebApi/Global.asax | 1 + SDWebApi/Global.asax.cs | 17 + SDWebApi/Properties/AssemblyInfo.cs | 35 ++ SDWebApi/SDWebApi.csproj | 187 +++++++++ SDWebApi/Web.Debug.config | 31 ++ SDWebApi/Web.Release.config | 32 ++ SDWebApi/Web.config | 63 +++ SDWebApi/packages.config | 21 + WcfControlMonitorLib/CCallService.cs | 3 +- WcfControlMonitorLib/CStaticClass.cs | 10 +- webapi/WindowsFormsApp1/APIChannel.cs | 108 ++++-- webapi/WindowsFormsApp1/App.config | 65 ++-- .../App_Start/SwaggerConfig.cs | 255 ++++++++++++ webapi/WindowsFormsApp1/DBFactory.dll.config | 30 ++ webapi/WindowsFormsApp1/WebAPI.csproj | 34 +- webapi/WindowsFormsApp1/packages.config | 14 +- 19 files changed, 1483 insertions(+), 67 deletions(-) create mode 100644 SDWebApi/App_Start/SwaggerConfig.cs create mode 100644 SDWebApi/App_Start/WebApiConfig.cs create mode 100644 SDWebApi/Controllers/thirdParty.cs create mode 100644 SDWebApi/Global.asax create mode 100644 SDWebApi/Global.asax.cs create mode 100644 SDWebApi/Properties/AssemblyInfo.cs create mode 100644 SDWebApi/SDWebApi.csproj create mode 100644 SDWebApi/Web.Debug.config create mode 100644 SDWebApi/Web.Release.config create mode 100644 SDWebApi/Web.config create mode 100644 SDWebApi/packages.config create mode 100644 webapi/WindowsFormsApp1/App_Start/SwaggerConfig.cs create mode 100644 webapi/WindowsFormsApp1/DBFactory.dll.config diff --git a/SDWebApi/App_Start/SwaggerConfig.cs b/SDWebApi/App_Start/SwaggerConfig.cs new file mode 100644 index 0000000..1781dd2 --- /dev/null +++ b/SDWebApi/App_Start/SwaggerConfig.cs @@ -0,0 +1,255 @@ +using System.Web.Http; +using WebActivatorEx; +using SDWebApi; +using Swashbuckle.Application; + +[assembly: PreApplicationStartMethod(typeof(SwaggerConfig), "Register")] + +namespace SDWebApi +{ + public class SwaggerConfig + { + public static void Register() + { + var thisAssembly = typeof(SwaggerConfig).Assembly; + + GlobalConfiguration.Configuration + .EnableSwagger(c => + { + // By default, the service root url is inferred from the request used to access the docs. + // However, there may be situations (e.g. proxy and load-balanced environments) where this does not + // resolve correctly. You can workaround this by providing your own code to determine the root URL. + // + //c.RootUrl(req => GetRootUrlFromAppConfig()); + + // If schemes are not explicitly provided in a Swagger 2.0 document, then the scheme used to access + // the docs is taken as the default. If your API supports multiple schemes and you want to be explicit + // about them, you can use the "Schemes" option as shown below. + // + //c.Schemes(new[] { "http", "https" }); + + // Use "SingleApiVersion" to describe a single version API. Swagger 2.0 includes an "Info" object to + // hold additional metadata for an API. Version and title are required but you can also provide + // additional fields by chaining methods off SingleApiVersion. + // + c.SingleApiVersion("v1", "ɽʱWebApi"); + + // If you want the output Swagger docs to be indented properly, enable the "PrettyPrint" option. + // + //c.PrettyPrint(); + + // If your API has multiple versions, use "MultipleApiVersions" instead of "SingleApiVersion". + // In this case, you must provide a lambda that tells Swashbuckle which actions should be + // included in the docs for a given API version. Like "SingleApiVersion", each call to "Version" + // returns an "Info" builder so you can provide additional metadata per API version. + // + //c.MultipleApiVersions( + // (apiDesc, targetApiVersion) => ResolveVersionSupportByRouteConstraint(apiDesc, targetApiVersion), + // (vc) => + // { + // vc.Version("v2", "Swashbuckle Dummy API V2"); + // vc.Version("v1", "Swashbuckle Dummy API V1"); + // }); + + // You can use "BasicAuth", "ApiKey" or "OAuth2" options to describe security schemes for the API. + // See https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md for more details. + // NOTE: These only define the schemes and need to be coupled with a corresponding "security" property + // at the document or operation level to indicate which schemes are required for an operation. To do this, + // you'll need to implement a custom IDocumentFilter and/or IOperationFilter to set these properties + // according to your specific authorization implementation + // + //c.BasicAuth("basic") + // .Description("Basic HTTP Authentication"); + // + // NOTE: You must also configure 'EnableApiKeySupport' below in the SwaggerUI section + //c.ApiKey("apiKey") + // .Description("API Key Authentication") + // .Name("apiKey") + // .In("header"); + // + //c.OAuth2("oauth2") + // .Description("OAuth2 Implicit Grant") + // .Flow("implicit") + // .AuthorizationUrl("http://petstore.swagger.wordnik.com/api/oauth/dialog") + // //.TokenUrl("https://tempuri.org/token") + // .Scopes(scopes => + // { + // scopes.Add("read", "Read access to protected resources"); + // scopes.Add("write", "Write access to protected resources"); + // }); + + // Set this flag to omit descriptions for any actions decorated with the Obsolete attribute + //c.IgnoreObsoleteActions(); + + // Each operation be assigned one or more tags which are then used by consumers for various reasons. + // For example, the swagger-ui groups operations according to the first tag of each operation. + // By default, this will be controller name but you can use the "GroupActionsBy" option to + // override with any value. + // + //c.GroupActionsBy(apiDesc => apiDesc.HttpMethod.ToString()); + + // You can also specify a custom sort order for groups (as defined by "GroupActionsBy") to dictate + // the order in which operations are listed. For example, if the default grouping is in place + // (controller name) and you specify a descending alphabetic sort order, then actions from a + // ProductsController will be listed before those from a CustomersController. This is typically + // used to customize the order of groupings in the swagger-ui. + // + //c.OrderActionGroupsBy(new DescendingAlphabeticComparer()); + + // If you annotate Controllers and API Types with + // Xml comments (http://msdn.microsoft.com/en-us/library/b2s063f7(v=vs.110).aspx), you can incorporate + // those comments into the generated docs and UI. You can enable this by providing the path to one or + // more Xml comment files. + // + //c.IncludeXmlComments(GetXmlCommentsPath()); + + // Swashbuckle makes a best attempt at generating Swagger compliant JSON schemas for the various types + // exposed in your API. However, there may be occasions when more control of the output is needed. + // This is supported through the "MapType" and "SchemaFilter" options: + // + // Use the "MapType" option to override the Schema generation for a specific type. + // It should be noted that the resulting Schema will be placed "inline" for any applicable Operations. + // While Swagger 2.0 supports inline definitions for "all" Schema types, the swagger-ui tool does not. + // It expects "complex" Schemas to be defined separately and referenced. For this reason, you should only + // use the "MapType" option when the resulting Schema is a primitive or array type. If you need to alter a + // complex Schema, use a Schema filter. + // + //c.MapType(() => new Schema { type = "integer", format = "int32" }); + + // If you want to post-modify "complex" Schemas once they've been generated, across the board or for a + // specific type, you can wire up one or more Schema filters. + // + //c.SchemaFilter(); + + // In a Swagger 2.0 document, complex types are typically declared globally and referenced by unique + // Schema Id. By default, Swashbuckle does NOT use the full type name in Schema Ids. In most cases, this + // works well because it prevents the "implementation detail" of type namespaces from leaking into your + // Swagger docs and UI. However, if you have multiple types in your API with the same class name, you'll + // need to opt out of this behavior to avoid Schema Id conflicts. + // + //c.UseFullTypeNameInSchemaIds(); + + // Alternatively, you can provide your own custom strategy for inferring SchemaId's for + // describing "complex" types in your API. + // + //c.SchemaId(t => t.FullName.Contains('`') ? t.FullName.Substring(0, t.FullName.IndexOf('`')) : t.FullName); + + // Set this flag to omit schema property descriptions for any type properties decorated with the + // Obsolete attribute + //c.IgnoreObsoleteProperties(); + + // In accordance with the built in JsonSerializer, Swashbuckle will, by default, describe enums as integers. + // You can change the serializer behavior by configuring the StringToEnumConverter globally or for a given + // enum type. Swashbuckle will honor this change out-of-the-box. However, if you use a different + // approach to serialize enums as strings, you can also force Swashbuckle to describe them as strings. + // + //c.DescribeAllEnumsAsStrings(); + + // Similar to Schema filters, Swashbuckle also supports Operation and Document filters: + // + // Post-modify Operation descriptions once they've been generated by wiring up one or more + // Operation filters. + // + //c.OperationFilter(); + // + // If you've defined an OAuth2 flow as described above, you could use a custom filter + // to inspect some attribute on each action and infer which (if any) OAuth2 scopes are required + // to execute the operation + // + //c.OperationFilter(); + + // Post-modify the entire Swagger document by wiring up one or more Document filters. + // This gives full control to modify the final SwaggerDocument. You should have a good understanding of + // the Swagger 2.0 spec. - https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md + // before using this option. + // + //c.DocumentFilter(); + + // In contrast to WebApi, Swagger 2.0 does not include the query string component when mapping a URL + // to an action. As a result, Swashbuckle will raise an exception if it encounters multiple actions + // with the same path (sans query string) and HTTP method. You can workaround this by providing a + // custom strategy to pick a winner or merge the descriptions for the purposes of the Swagger docs + // + //c.ResolveConflictingActions(apiDescriptions => apiDescriptions.First()); + + // Wrap the default SwaggerGenerator with additional behavior (e.g. caching) or provide an + // alternative implementation for ISwaggerProvider with the CustomProvider option. + // + //c.CustomProvider((defaultProvider) => new CachingSwaggerProvider(defaultProvider)); + }) + .EnableSwaggerUi(c => + { + // Use the "DocumentTitle" option to change the Document title. + // Very helpful when you have multiple Swagger pages open, to tell them apart. + // + //c.DocumentTitle("My Swagger UI"); + + // Use the "InjectStylesheet" option to enrich the UI with one or more additional CSS stylesheets. + // The file must be included in your project as an "Embedded Resource", and then the resource's + // "Logical Name" is passed to the method as shown below. + // + //c.InjectStylesheet(containingAssembly, "Swashbuckle.Dummy.SwaggerExtensions.testStyles1.css"); + + // Use the "InjectJavaScript" option to invoke one or more custom JavaScripts after the swagger-ui + // has loaded. The file must be included in your project as an "Embedded Resource", and then the resource's + // "Logical Name" is passed to the method as shown above. + // + //c.InjectJavaScript(thisAssembly, "Swashbuckle.Dummy.SwaggerExtensions.testScript1.js"); + + // The swagger-ui renders boolean data types as a dropdown. By default, it provides "true" and "false" + // strings as the possible choices. You can use this option to change these to something else, + // for example 0 and 1. + // + //c.BooleanValues(new[] { "0", "1" }); + + // By default, swagger-ui will validate specs against swagger.io's online validator and display the result + // in a badge at the bottom of the page. Use these options to set a different validator URL or to disable the + // feature entirely. + //c.SetValidatorUrl("http://localhost/validator"); + //c.DisableValidator(); + + // Use this option to control how the Operation listing is displayed. + // It can be set to "None" (default), "List" (shows operations for each resource), + // or "Full" (fully expanded: shows operations and their details). + // + //c.DocExpansion(DocExpansion.List); + + // Specify which HTTP operations will have the 'Try it out!' option. An empty paramter list disables + // it for all operations. + // + //c.SupportedSubmitMethods("GET", "HEAD"); + + // Use the CustomAsset option to provide your own version of assets used in the swagger-ui. + // It's typically used to instruct Swashbuckle to return your version instead of the default + // when a request is made for "index.html". As with all custom content, the file must be included + // in your project as an "Embedded Resource", and then the resource's "Logical Name" is passed to + // the method as shown below. + // + //c.CustomAsset("index", containingAssembly, "YourWebApiProject.SwaggerExtensions.index.html"); + + // If your API has multiple versions and you've applied the MultipleApiVersions setting + // as described above, you can also enable a select box in the swagger-ui, that displays + // a discovery URL for each version. This provides a convenient way for users to browse documentation + // for different API versions. + // + //c.EnableDiscoveryUrlSelector(); + + // If your API supports the OAuth2 Implicit flow, and you've described it correctly, according to + // the Swagger 2.0 specification, you can enable UI support as shown below. + // + //c.EnableOAuth2Support( + // clientId: "test-client-id", + // clientSecret: null, + // realm: "test-realm", + // appName: "Swagger UI" + // //additionalQueryStringParams: new Dictionary() { { "foo", "bar" } } + //); + + // If your API supports ApiKey, you can override the default values. + // "apiKeyIn" can either be "query" or "header" + // + //c.EnableApiKeySupport("apiKey", "header"); + }); + } + } +} diff --git a/SDWebApi/App_Start/WebApiConfig.cs b/SDWebApi/App_Start/WebApiConfig.cs new file mode 100644 index 0000000..8f3a76d --- /dev/null +++ b/SDWebApi/App_Start/WebApiConfig.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web.Http; + +namespace SDWebApi +{ + public static class WebApiConfig + { + public static void Register(HttpConfiguration config) + { + // Web API 配置和服务 + + // Web API 路由 + config.MapHttpAttributeRoutes(); + + config.Routes.MapHttpRoute( + name: "DefaultApi", + routeTemplate: "api/{controller}/{id}", + defaults: new { id = RouteParameter.Optional } + ); + } + } +} diff --git a/SDWebApi/Controllers/thirdParty.cs b/SDWebApi/Controllers/thirdParty.cs new file mode 100644 index 0000000..d92a786 --- /dev/null +++ b/SDWebApi/Controllers/thirdParty.cs @@ -0,0 +1,365 @@ +using DBFactory; +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Net; +using System.Net.Http; +using System.Text; +using System.Web.Http; +using WcfControlMonitorLib; + +namespace SDWebApi.Controllers +{ + [RoutePrefix("api/wcs")] + public class thirdParty : ApiController + { + static DBOperator dbo = CStaticClass.dbo; + static DBOperator dboMan = CStaticClass.dboM; + static String ERROR = String.Empty; + [HttpPost] + [Route("receiveWmsTask")] + // POST api/ + public string receiveWmsTaskController([FromBody] string value) + { + dbo.TransBegin(IsolationLevel.ReadCommitted); + try + { + //var body = this.Request.Body; + //int length = (int)body.Length; + //byte[] data = new byte[length]; + //body.Read(data, 0, length); + //string jsonStr = System.Text.Encoding.Default.GetString(value); + CommonClassLib.CCarryConvert.WriteLog("WEBAPI", "收到报文", value.ToString(), ""); + + CCallService.WMS_WCS_PARAM_OUT_MOVE wms_wcs = Model.JsonHelper.Deserialize(value); + // CCallService.WCS_WMS_PARAM_OUT_MOVE wcs_wms = new CCallService.WCS_WMS_PARAM_OUT_MOVE(); //返回的报文 + CCallService.OUT_MOVE_RES answer_outdata = new CCallService.OUT_MOVE_RES();//返回数据 + string err = string.Empty; + string returnJson = string.Empty; + DataView dv = new DataView(); + CCallService.OUT_MOVE_RES outReturn = new CCallService.OUT_MOVE_RES(); + if (wms_wcs != null) + { + List outdata = wms_wcs.tasks; //任务信息 + int isOk = 0; + // CCallService.OUT_MOVE_RES outReturn = new CCallService.OUT_MOVE_RES(); + foreach (var task in outdata) + { + + IO_CONTROL outtask = new IO_CONTROL(task, wms_wcs.msgTime, wms_wcs.priority.ToString()); + + if (outtask.Insert_IOCONTROL() == false) + { + isOk++; + outReturn.data += "ID'" + task.taskId.ToString() + "'任务下发失败:"; + } + if (isOk == 0) + { + outReturn.code = 0; + outReturn.msg = ""; + } + else + { + outReturn.code = 1; + outReturn.msg = "任务接收失败"; + } + } + + } + returnJson = Model.JsonHelper.Serializer(outReturn); + CommonClassLib.CCarryConvert.WriteLog("WEBAPI", "返回报文", returnJson, ""); + dbo.TransCommit(); + return returnJson; + } + catch (Exception ex) + { + string errorjson = Model.JsonHelper.Serializer(new + { + code = 1, + msg = "WCS解析json异常", + data = ex.Message.ToString() + }); + CommonClassLib.CCarryConvert.WriteLog("WEBAPI", "返回报文", ex.Message.ToString(), ""); + dbo.TransRollback(); + return errorjson; + } + } + + // PUT api//5 + public void Put(int id, [FromBody] string value) + { + } + + // DELETE api//5 + public void Delete(int id) + { + } + } + + #region 向 IO_CONTROL 插入出库倒库任务等 + public class IO_CONTROL + { + static DBOperator dbo = CStaticClass.dbo; + static DBOperator dboMan = CStaticClass.dboM; + string wms_id; + int relative_id; + string barcode; + string startdevice; + string enddevice; + string begintime; + int control_type; + string warehouse = "1"; + string tasklevel; + int needAgv = 0; + public StringBuilder error_code = new StringBuilder(); + + StringBuilder sql = new StringBuilder(); + + public IO_CONTROL(CCallService.OUT_MOVE_DATA outdata, string time, string level)//出库 移库 + { + error_code.Clear(); + wms_id = outdata.taskId; + relative_id = -1; + barcode = outdata.containerCode; + if (outdata.taskType == 2 || outdata.taskType == 3) + { //起点是库位 + startdevice = outdata.startRow.ToString("D2") + "-" + outdata.startColumn.ToString("D2") + "-" + outdata.startLayer.ToString("D2"); + enddevice = outdata.endNode; + } + else if (outdata.taskType == 1 || outdata.taskType == 4) //终点是库位 + { + startdevice = outdata.startNode; + enddevice = outdata.endRow.ToString("D2") + "-" + outdata.endColumn.ToString("D2") + "-" + outdata.endLayer.ToString("D2"); + } + control_type = outdata.taskType; + string dTime1 = DateTime.Now.ToString("u"); + begintime = dTime1.Substring(0, dTime1.Length - 1); + tasklevel = level; + // needAgv = outdata.carryType == 2 ? 1 : 0; + } + public IO_CONTROL(CCallService.WMS_WCS_PARAM_IN indata, string time, string level)//入库 + { + error_code.Clear(); + wms_id = indata.taskId; + relative_id = -1; + barcode = indata.containerCode; + if (indata.taskType == 2 || indata.taskType == 3) + { //起点是库位 + // startdevice = outdata.startRow.ToString("D2") + "-" + outdata.startColumn.ToString("D2") + "-" + outdata.startLayer.ToString("D2"); + enddevice = indata.endNode; + } + else if (indata.taskType == 1 || indata.taskType == 4) //终点是库位 + { + startdevice = indata.startNode; + enddevice = indata.endRow.ToString("D2") + "-" + indata.endColumn.ToString("D2") + "-" + indata.endLayer.ToString("D2"); + } + control_type = 1; + string dTime1 = DateTime.Now.ToString("u"); + begintime = dTime1.Substring(0, dTime1.Length - 1); + tasklevel = level; + + } + + //检查参数是否正确 + bool CheckData() + { + Dictionary all_checking = new Dictionary(); + + #region 从数据库中读取要检测的SQL + sql.Clear(); + sql.Append("select * from WEBAPI_CKECKING"); + DataView dv = dbo.ExceSQL(sql.ToString()).Tables[0].DefaultView; + for (int i = 0; i < dv.Count; i++) + { + WEBAPI_CKECKING wac = new WEBAPI_CKECKING(); + + wac.check_id = dv[i]["CKECK_ID"].ToString(); + wac.check_name = dv[i]["CKECK_NAME"].ToString(); + wac.sql = dv[i]["SQL"].ToString(); + wac.des = dv[i]["DESCRIPTION"].ToString(); + + all_checking.Add(wac.check_name, wac); + } + #endregion + + error_code.Clear(); + + #region 检查是否重复,CONTROL_ID, 托盘码重复, 起始货位重复,终止货位重复(结果大于零) + + sql.Clear(); + sql.Append(string.Format(all_checking["CONTROL_ID_REPEAT"].sql, wms_id)); + if (dbo.ExceSQL(sql.ToString()).Tables[0].DefaultView.Count > 0) + { + error_code.Append(";").Append(all_checking["CONTROL_ID_REPEAT"].des); //fid重复 + } + + //sql.Clear(); + //sql.Append(string.Format(all_checking["BARCODE_REPEAT"].sql, barcode)); + //if (dbo.ExceSQL(sql.ToString()).Tables[0].DefaultView.Count > 0) + //{ + // error_code.Append(";").Append(all_checking["BARCODE_REPEAT"].des); //托盘条码重复 + //} + if (string.IsNullOrEmpty(tasklevel)) + { + error_code.Append(";").Append("任务优先级为空"); + } + if (string.IsNullOrEmpty(wms_id)) + { + error_code.Append(";").Append("任务号为空"); + } + if (string.IsNullOrEmpty(barcode)) + { + error_code.Append(";").Append("条码为空"); + } + + if (int.TryParse(this.wms_id, out int controlid) == false) + { + error_code.Append(";").Append(all_checking["CONTROL_ID_NOT_NUM"].des); //controlid不为数字 + } + + + if (control_type == 2)//出库任务 + { + + sql.Clear(); + sql.Append(string.Format(all_checking["START_CEEE_REPEAT"].sql, startdevice, control_type)); + if (dbo.ExceSQL(sql.ToString()).Tables[0].DefaultView.Count > 0) + { + error_code.Append(";").Append(all_checking["START_CEEE_REPEAT"].des); //起始货位重复 + } + if (this.startdevice.Length != 8) + { + error_code.Append(";").Append("起点").Append(all_checking["CELL_LENGTH_ERROR"].des); //起点货位编码长度错误 + } + sql.Clear(); + sql.Append(string.Format(all_checking["CELL_NOT_EXIST"].sql, startdevice)); + if (dbo.ExceSQL(sql.ToString()).Tables[0].DefaultView.Count == 0) + { + error_code.Append(";").Append("起点").Append(all_checking["CELL_NOT_EXIST"].des); //起点货位不存在 + + } + + int endGate = 0; + if (int.TryParse(this.enddevice, out endGate) == false) + { + error_code.Append(";").Append(all_checking["END_GATE_ERROR"].des); //终点站台不正确,无法转为整数 + } + + sql.Clear(); + sql.Append(string.Format(all_checking["END_GATE_NOT_EXIST"].sql, enddevice)); + if (dbo.ExceSQL(sql.ToString()).Tables[0].DefaultView.Count == 0) + { + error_code.Append(";").Append(all_checking["END_GATE_NOT_EXIST"].des); //终点站台不存在 + } + + } + + if (control_type == 1)//入库任务 + { + sql.Clear(); + sql.Append(string.Format(all_checking["END_CEEE_REPEAT"].sql, enddevice, control_type)); + if (dbo.ExceSQL(sql.ToString()).Tables[0].DefaultView.Count > 0) + { + error_code.Append(";").Append(all_checking["END_CEEE_REPEAT"].des); //终点货位重复 + } + if (this.enddevice.Length != 8) + { + error_code.Append(";").Append("终点").Append(all_checking["CELL_LENGTH_ERROR"].des); //终点货位编码长度错误 + } + + sql.Clear(); + sql.Append(string.Format(all_checking["CELL_NOT_EXIST"].sql, enddevice)); + if (dbo.ExceSQL(sql.ToString()).Tables[0].DefaultView.Count == 0) + { + error_code.Append(";").Append("终点").Append(all_checking["CELL_NOT_EXIST"].des); //终点货位不存在 + } + sql.Clear(); + sql.Append(string.Format(all_checking["START_GATE_NOT_EXIST"].sql, startdevice)); + if (dbo.ExceSQL(sql.ToString()).Tables[0].DefaultView.Count == 0) + { + error_code.Append(";").Append(all_checking["START_GATE_NOT_EXIST"].des); //起点站台不存在 + } + } + #region 校验代码需优化20250310 + if (control_type == 3) //移库任务 + { + if (this.startdevice.Length != 8) + { + error_code.Append(";").Append("起点").Append(all_checking["CELL_LENGTH_ERROR"].des); //终点货位编码长度错误 + } + if (this.enddevice.Length != 8) + { + error_code.Append(";").Append("终点").Append(all_checking["CELL_LENGTH_ERROR"].des); //终点货位编码长度错误 + } + + sql.Clear(); + sql.Append(string.Format(all_checking["CELL_NOT_EXIST"].sql, startdevice)); + if (dbo.ExceSQL(sql.ToString()).Tables[0].DefaultView.Count == 0) + { + error_code.Append(";").Append("起点").Append(all_checking["CELL_NOT_EXIST"].des); //起点货位不存在 + + } + sql.Clear(); + sql.Append(string.Format(all_checking["CELL_NOT_EXIST"].sql, enddevice)); + if (dbo.ExceSQL(sql.ToString()).Tables[0].DefaultView.Count == 0) + { + error_code.Append(";").Append("终点").Append(all_checking["CELL_NOT_EXIST"].des); //终点货位不存在 + } + + //移库任务如果不同层,校验不要移 + if (startdevice.Substring(6, 2) != enddevice.Substring(6, 2)) + { + error_code.Append(";").Append("移库任务起点终点层值不同"); + } + if (startdevice == enddevice) + { + error_code.Append(";").Append("移库任务起点终点相同"); + } + + } + #endregion + #endregion + + //检查托盘码 + + if (error_code.Length == 0) + { + return true; + } + else + { + return false; + } + } + + // + public bool Insert_IOCONTROL() + { + if (CheckData() == true) + { + try + { + sql.Clear(); + sql.Append(string.Format("INSERT INTO IO_CONTROL (CONTROL_ID, RELATIVE_CONTROL_ID, MANAGE_ID, STOCK_BARCODE, CONTROL_TASK_TYPE, CONTROL_TASK_LEVEL," + + " START_WAREHOUSE_CODE, START_DEVICE_CODE, END_WAREHOUSE_CODE, END_DEVICE_CODE, CONTROL_BEGIN_TIME,CONTROL_STATUS,NeedAgv) " + + "VALUES( {0},'{1}','{2}', '{3}', '{4}', '{5}', '{6}', '{7}', '{8}', '{9}', '{10}',{11})", + wms_id, -1, 0, barcode, control_type, tasklevel, warehouse, startdevice, warehouse, enddevice, begintime, 0, needAgv)); + dbo.ExceSQL(sql.ToString()); + return true; + } + catch (Exception ex) + { + error_code.Append("WCS插入IO_ONTROL表失败!"); + return false; + } + } + + return false; + } + + + } + #endregion + +} \ No newline at end of file diff --git a/SDWebApi/Global.asax b/SDWebApi/Global.asax new file mode 100644 index 0000000..9b1f74b --- /dev/null +++ b/SDWebApi/Global.asax @@ -0,0 +1 @@ +<%@ Application Codebehind="Global.asax.cs" Inherits="SDWebApi.WebApiApplication" Language="C#" %> diff --git a/SDWebApi/Global.asax.cs b/SDWebApi/Global.asax.cs new file mode 100644 index 0000000..57491a2 --- /dev/null +++ b/SDWebApi/Global.asax.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web; +using System.Web.Http; +using System.Web.Routing; + +namespace SDWebApi +{ + public class WebApiApplication : System.Web.HttpApplication + { + protected void Application_Start() + { + GlobalConfiguration.Configure(WebApiConfig.Register); + } + } +} diff --git a/SDWebApi/Properties/AssemblyInfo.cs b/SDWebApi/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..98d67d3 --- /dev/null +++ b/SDWebApi/Properties/AssemblyInfo.cs @@ -0,0 +1,35 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// 有关程序集的常规信息通过下列特性集 +// 控制。更改这些特性值可修改 +// 与程序集关联的信息。 +[assembly: AssemblyTitle("SDWebApi")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("SDWebApi")] +[assembly: AssemblyCopyright("Copyright © 2025")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// 将 ComVisible 设置为 false 会使此程序集中的类型 +// 对 COM 组件不可见。如果需要 +// 从 COM 访问此程序集中的某个类型,请针对该类型将 ComVisible 特性设置为 true。 +[assembly: ComVisible(false)] + +// 如果此项目向 COM 公开,则下列 GUID 用于 typelib 的 ID +[assembly: Guid("75a6ab90-58b1-4f0b-a735-9fc834d91fee")] + +// 程序集的版本信息由下列四个值组成: +// +// 主版本 +// 次版本 +// 内部版本号 +// 修订版本 +// +// 可以指定所有值,也可以使用“修订号”和“内部版本号”的默认值, +// 方法是按如下所示使用 "*": +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/SDWebApi/SDWebApi.csproj b/SDWebApi/SDWebApi.csproj new file mode 100644 index 0000000..8c6873e --- /dev/null +++ b/SDWebApi/SDWebApi.csproj @@ -0,0 +1,187 @@ + + + + Debug + AnyCPU + + + 2.0 + {75A6AB90-58B1-4F0B-A735-9FC834D91FEE} + {349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc} + Library + Properties + SDWebApi + SDWebApi + v4.5.2 + true + + 44377 + + + + + + + + + true + full + false + bin\ + DEBUG;TRACE + prompt + 4 + bin\SDWebApi.xml + + + true + pdbonly + true + bin\ + TRACE + prompt + 4 + + + + ..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.3.6.0\lib\net45\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.dll + + + + ..\packages\Microsoft.Web.Infrastructure.2.0.0\lib\net40\Microsoft.Web.Infrastructure.dll + + + ..\packages\Newtonsoft.Json.13.0.1\lib\net45\Newtonsoft.Json.dll + + + ..\packages\Newtonsoft.Json.Bson.1.0.2\lib\net45\Newtonsoft.Json.Bson.dll + + + ..\packages\Swashbuckle.Core.5.6.0\lib\net40\Swashbuckle.Core.dll + + + ..\packages\System.Buffers.4.5.1\lib\netstandard1.1\System.Buffers.dll + + + ..\packages\System.Memory.4.5.5\lib\netstandard1.1\System.Memory.dll + + + + ..\packages\Microsoft.AspNet.WebApi.Client.6.0.0\lib\net45\System.Net.Http.Formatting.dll + + + ..\packages\System.Runtime.CompilerServices.Unsafe.4.5.3\lib\netstandard1.0\System.Runtime.CompilerServices.Unsafe.dll + + + ..\packages\System.Threading.Tasks.Extensions.4.5.4\lib\portable-net45+win8+wp8+wpa81\System.Threading.Tasks.Extensions.dll + + + + + + + + + + + + ..\packages\Microsoft.AspNet.WebApi.Core.5.3.0\lib\net45\System.Web.Http.dll + + + ..\packages\Microsoft.AspNet.WebApi.WebHost.5.3.0\lib\net45\System.Web.Http.WebHost.dll + + + + + + + + + + ..\packages\WebActivatorEx.2.2.0\lib\net40\WebActivatorEx.dll + + + + + + + + + + + + Global.asax + + + + + + + Web.config + + + Web.config + + + + + + + + + {a2215dce-aa3a-4b1e-b732-e97fd4c454d5} + CommonClassLib + + + {4e27122e-93a2-4d17-b8b5-63fac14f73c0} + DBFactory + + + {f1c29e02-62a1-44c7-b71d-993e089d8c97} + Model + + + {fabc3752-18fe-454e-a86f-4ddccc5ef6bb} + WcfControlMonitorLib + + + + 10.0 + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) + + + + + + + + + True + True + 53877 + / + https://localhost:44377/ + False + False + + + False + + + + + + + + 这台计算机上缺少此项目引用的 NuGet 程序包。使用“NuGet 程序包还原”可下载这些程序包。有关更多信息,请参见 http://go.microsoft.com/fwlink/?LinkID=322105。缺少的文件是 {0}。 + + + + + \ No newline at end of file diff --git a/SDWebApi/Web.Debug.config b/SDWebApi/Web.Debug.config new file mode 100644 index 0000000..b9a9fde --- /dev/null +++ b/SDWebApi/Web.Debug.config @@ -0,0 +1,31 @@ + + + + + + + + + + \ No newline at end of file diff --git a/SDWebApi/Web.Release.config b/SDWebApi/Web.Release.config new file mode 100644 index 0000000..755e745 --- /dev/null +++ b/SDWebApi/Web.Release.config @@ -0,0 +1,32 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/SDWebApi/Web.config b/SDWebApi/Web.config new file mode 100644 index 0000000..5848a2b --- /dev/null +++ b/SDWebApi/Web.config @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/SDWebApi/packages.config b/SDWebApi/packages.config new file mode 100644 index 0000000..9d14ef9 --- /dev/null +++ b/SDWebApi/packages.config @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/WcfControlMonitorLib/CCallService.cs b/WcfControlMonitorLib/CCallService.cs index b1c2607..1648f13 100644 --- a/WcfControlMonitorLib/CCallService.cs +++ b/WcfControlMonitorLib/CCallService.cs @@ -1042,7 +1042,7 @@ namespace WcfControlMonitorLib sql.Clear(); DataView data = new DataView(); sql.Append(string.Format("select CONTROL_ID,MANAGE_ID,CONTROL_TASK_TYPE, STOCK_BARCODE, START_WAREHOUSE_CODE,START_DEVICE_CODE, END_WAREHOUSE_CODE, END_DEVICE_CODE, CONTROL_BEGIN_TIME,CONTROL_STATUS,NeedAGV from IO_CONTROL where FMANAGE_ID={0}", Managertask_Id)); - data = dbo.ExceSQL(sql.ToString()).Tables[0].DefaultView; ; + data = dbo.ExceSQL(sql.ToString()).Tables[0].DefaultView; WCS_WMS_PARAM_UPDATE upd = new WCS_WMS_PARAM_UPDATE();//传参解析使用 if (data.Count > 0) { upd.taskId = Managertask_Id.ToString(); @@ -1513,6 +1513,7 @@ namespace WcfControlMonitorLib { SControlMonitor sControl = new SControlMonitor(); sControl.WriteDBDataConveyor(Convert.ToInt32(dv[i]["F_DeviceIndex"]), "DB2", dv[i]["F_AGVStatus"].ToString(), out string errtext); + // } } } diff --git a/WcfControlMonitorLib/CStaticClass.cs b/WcfControlMonitorLib/CStaticClass.cs index 1f45bfc..38b8d67 100644 --- a/WcfControlMonitorLib/CStaticClass.cs +++ b/WcfControlMonitorLib/CStaticClass.cs @@ -114,11 +114,11 @@ namespace WcfControlMonitorLib //20091107 - static string _ManageServiceAddress = "http://ip:˿/lcs/thirdParty/taskStatusReport";//WCS ִйִ̣е״̬ش LCS ϵͳ - static string _ManageServiceAddress2 = "http://ip:˿/lcs/thirdParty/inboundApply";//ҵҪⲿɨ豸λУǷʱWCS ͨ ӿ LCS 롣 - static string _ManageServiceAddress3 = "http://ip:˿/lcs/thirdParty/wcsTaskInfo";//WCS ֪ͨ LCS AGV ȡ - static string _ManageServiceAddress4 = "https://ip:˿/api/lcs/thirdParty/requestRescore";//WCS ͨýӿ LCS Ŀλ·䡣 - static string _ManageServiceAddress5 = "https://ip:˿/api/lcs/thirdParty/autoMoveOut";//WCS WMS жǷҪԶƿ + static string _ManageServiceAddress = "http://localhost:525/lcs/thirdParty/taskStatusReport";//WCS ִйִ̣е״̬ش LCS ϵͳ + static string _ManageServiceAddress2 = "http://localhost:5252/lcs/thirdParty/inboundApply";//ҵҪⲿɨ豸λУǷʱWCS ͨ ӿ LCS 롣 + static string _ManageServiceAddress3 = "http://localhost:5252/lcs/thirdParty/wcsTaskInfo";//WCS ֪ͨ LCS AGV ȡ + static string _ManageServiceAddress4 = "http://localhost:5252/api/lcs/thirdParty/requestRescore";//WCS ͨýӿ LCS Ŀλ·䡣 + static string _ManageServiceAddress5 = "http://localhost:5252/api/lcs/thirdParty/autoMoveOut";//WCS WMS жǷҪԶƿ public static string ManageServiceAddress { diff --git a/webapi/WindowsFormsApp1/APIChannel.cs b/webapi/WindowsFormsApp1/APIChannel.cs index ae1df5a..9bba752 100644 --- a/webapi/WindowsFormsApp1/APIChannel.cs +++ b/webapi/WindowsFormsApp1/APIChannel.cs @@ -43,7 +43,7 @@ namespace WindowsFormsApp1 public APIChannel() { - Get["/"] = _ => "This is WCS APIServer"; + Get["/api/wcs/thirdParty"] = _ => "This is WCS APIServer"; ////查询 //Post["/api/BindTrayInfo/AgvGetBindTrayInfo", true] = async (x, ct) => //{ @@ -56,14 +56,15 @@ namespace WindowsFormsApp1 // return "a";//I_ManageClient.HandleControlAGVQueryApplyYB(jsonStr); //}; - + // #region WMS调用, 在此处理,出库以及移库任务 多条任务 任务下发 Post["/api/wcs/thirdParty/receiveWmsTask", true] = async (x, ct) => { - dbo.TransBegin(IsolationLevel.ReadCommitted); + dbo.TransBegin(); try { + var body = this.Request.Body; int length = (int)body.Length; byte[] data = new byte[length]; @@ -86,13 +87,21 @@ namespace WindowsFormsApp1 foreach (var task in outdata) { - IO_CONTROL outtask = new IO_CONTROL(task, wms_wcs.msgTime, task.taskType, wms_wcs.priority.ToString()); - - if (outtask.Insert_IOCONTROL() == false) + IO_CONTROL outtask = new IO_CONTROL(task, wms_wcs.msgTime, wms_wcs.priority.ToString()); + if (outtask.CheckData( out string msg) == true) { + outtask.sql.Clear(); + outtask.sql.Append(string.Format("INSERT INTO IO_CONTROL (CONTROL_ID, RELATIVE_CONTROL_ID, MANAGE_ID, STOCK_BARCODE, CONTROL_TASK_TYPE, CONTROL_TASK_LEVEL," + + " START_WAREHOUSE_CODE, START_DEVICE_CODE, END_WAREHOUSE_CODE, END_DEVICE_CODE, CONTROL_BEGIN_TIME,CONTROL_STATUS) " + + "VALUES( {0},'{1}','{2}', '{3}', '{4}', '{5}', '{6}', '{7}', '{8}', '{9}', '{10}',{11})", + outtask.wms_id, -1, 0, outtask.barcode, outtask.control_type, outtask.tasklevel, outtask.warehouse, outtask.startdevice, outtask.warehouse, outtask.enddevice, outtask.begintime, 0)); + dbo.ExceSQL(outtask.sql.ToString()); + + } + else { isOk++; - outReturn.data += "ID'" + task.taskId.ToString() + "'任务下发失败:"; - } + outReturn.data += "ID'" + task.taskId.ToString() + $"'任务下发失败:{msg}"; + } if (isOk == 0) { outReturn.code = 0; @@ -128,6 +137,7 @@ namespace WindowsFormsApp1 #region WMS调用, 在此处理,取消任务 单条形式 Post["/api/wcs/thirdParty/cancelWmsTask", true] = async (x, ct) => { + dbo.TransBegin(); try { var body = this.Request.Body; @@ -141,6 +151,7 @@ namespace WindowsFormsApp1 string err = string.Empty; string returnJson = string.Empty; DataView dv = new DataView(); + DataView dv1 = new DataView(); if (wms_wcs_cancel != null) { //CCallService.CANCEL_DATA canceldata = new CCallService.CANCEL_DATA(); @@ -148,9 +159,8 @@ namespace WindowsFormsApp1 // CCallService.CANCEL_RES_DATA cancelReturn = new CCallService.CANCEL_RES_DATA(); string sql = "select * from t_manage_task where FID = '" + wms_wcs_cancel.taskId + "'"; dv = dbo.ExceSQL(sql).Tables[0].DefaultView; - if (dv.Count == 1) - { - + if (dv.Count == 1) + { int stepOk = Convert.ToInt32(dv[0]["FIntoStepOK"]);//拆分下发 if (stepOk == 0)//未拆分 { @@ -184,10 +194,10 @@ namespace WindowsFormsApp1 wcs_wms_cancel.msg = "取消任务失败,任务已执行!"; wcs_wms_cancel.data = ""; } - } else if (dv.Count == 0) { + wcs_wms_cancel.code = 0; wcs_wms_cancel.msg = "取消任务成功,WCS中无此任务!" + wms_wcs_cancel.taskId; wcs_wms_cancel.data = ""; @@ -198,10 +208,19 @@ namespace WindowsFormsApp1 wcs_wms_cancel.code = 1; wcs_wms_cancel.msg = "取消任务失败,WCS中有多条相同任务!"; wcs_wms_cancel.data = ""; - } + } + if (wcs_wms_cancel.code == 0) {//删除成功 + string sql1 = "select * from IO_CONTROL where CONTROL_ID = '" + wms_wcs_cancel.taskId + "'"; + dv1 = dbo.ExceSQL(sql1).Tables[0].DefaultView; + if (dv1.Count > 0) { + string sql2 = "delete from IO_CONTROL where CONTROL_ID = '" + wms_wcs_cancel.taskId + "'"; + dbo.ExceSQL(sql2); + } + } } returnJson = Model.JsonHelper.Serializer(wcs_wms_cancel); CommonClassLib.CCarryConvert.WriteLog("WEBAPI", "返回报文", returnJson, ""); + dbo.TransCommit(); return returnJson; } catch (Exception ex) @@ -213,6 +232,7 @@ namespace WindowsFormsApp1 data = ex.Message.ToString() }); CommonClassLib.CCarryConvert.WriteLog("WEBAPI", "返回报文", ex.Message.ToString(), ""); + dbo.TransRollback(); return errorjson; } }; @@ -581,21 +601,21 @@ namespace WindowsFormsApp1 #region 向 IO_CONTROL 插入出库倒库任务等 public class IO_CONTROL { - string wms_id; - int relative_id; - string barcode; - string startdevice; - string enddevice; - string begintime; - int control_type; - string warehouse ="1"; - string tasklevel; - int needAgv = 0; + public string wms_id; + public int relative_id; + public string barcode; + public string startdevice; + public string enddevice; + public string begintime; + public int control_type; + public string warehouse ="1"; + public string tasklevel; + public int needAgv = 0; public StringBuilder error_code = new StringBuilder(); - StringBuilder sql = new StringBuilder(); + public StringBuilder sql = new StringBuilder(); - public IO_CONTROL(CCallService.OUT_MOVE_DATA outdata, string time,int controltype,string level)//出库 移库 + public IO_CONTROL(CCallService.OUT_MOVE_DATA outdata, string time,string level)//出库 移库 { error_code.Clear(); wms_id = outdata.taskId; @@ -611,11 +631,11 @@ namespace WindowsFormsApp1 startdevice = outdata.startNode; enddevice = outdata.endRow.ToString("D2") + "-" + outdata.endColumn.ToString("D2") + "-" + outdata.endLayer.ToString("D2"); } - control_type = controltype; + control_type = outdata.taskType; string dTime1 = DateTime.Now.ToString("u"); begintime = dTime1.Substring(0, dTime1.Length - 1); tasklevel = level; - needAgv = outdata.carryType == 2 ? 1 : 0; + // needAgv = outdata.carryType == 2 ? 1 : 0; } public IO_CONTROL(CCallService.WMS_WCS_PARAM_IN indata, string time, string level)//入库 { @@ -641,7 +661,7 @@ namespace WindowsFormsApp1 } //检查参数是否正确 - bool CheckData() + public bool CheckData( out string msg) { Dictionary all_checking = new Dictionary(); @@ -804,18 +824,20 @@ namespace WindowsFormsApp1 if (error_code.Length == 0) { + msg = ""; return true; } else { + msg = error_code.ToString(); return false; } } // - public bool Insert_IOCONTROL() + public bool Insert_IOCONTROL(DBOperator db) { - if (CheckData() == true) + if (CheckData( out string msg) == true) { try { @@ -824,7 +846,7 @@ namespace WindowsFormsApp1 " START_WAREHOUSE_CODE, START_DEVICE_CODE, END_WAREHOUSE_CODE, END_DEVICE_CODE, CONTROL_BEGIN_TIME,CONTROL_STATUS,NeedAgv) " + "VALUES( {0},'{1}','{2}', '{3}', '{4}', '{5}', '{6}', '{7}', '{8}', '{9}', '{10}',{11})", wms_id, -1, 0, barcode, control_type, tasklevel, warehouse, startdevice, warehouse, enddevice, begintime,0,needAgv)); - dbo.ExceSQL(sql.ToString()); + db.ExceSQL(sql.ToString()); return true; } catch(Exception ex) @@ -837,7 +859,29 @@ namespace WindowsFormsApp1 return false; } - + public bool Insert_IOCONTROL() + { + if (CheckData(out string msg ) == true) + { + try + { + sql.Clear(); + sql.Append(string.Format("INSERT INTO IO_CONTROL (CONTROL_ID, RELATIVE_CONTROL_ID, MANAGE_ID, STOCK_BARCODE, CONTROL_TASK_TYPE, CONTROL_TASK_LEVEL," + + " START_WAREHOUSE_CODE, START_DEVICE_CODE, END_WAREHOUSE_CODE, END_DEVICE_CODE, CONTROL_BEGIN_TIME,CONTROL_STATUS,NeedAgv) " + + "VALUES( {0},'{1}','{2}', '{3}', '{4}', '{5}', '{6}', '{7}', '{8}', '{9}', '{10}',{11})", + wms_id, -1, 0, barcode, control_type, tasklevel, warehouse, startdevice, warehouse, enddevice, begintime, 0, needAgv)); + dbo.ExceSQL(sql.ToString()); + return true; + } + catch (Exception ex) + { + error_code.Append("WCS插入IO_ONTROL表失败!"); + return false; + } + } + + return false; + } } #endregion diff --git a/webapi/WindowsFormsApp1/App.config b/webapi/WindowsFormsApp1/App.config index b119271..88c4d60 100644 --- a/webapi/WindowsFormsApp1/App.config +++ b/webapi/WindowsFormsApp1/App.config @@ -1,24 +1,45 @@ - + - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/webapi/WindowsFormsApp1/App_Start/SwaggerConfig.cs b/webapi/WindowsFormsApp1/App_Start/SwaggerConfig.cs new file mode 100644 index 0000000..cb92f41 --- /dev/null +++ b/webapi/WindowsFormsApp1/App_Start/SwaggerConfig.cs @@ -0,0 +1,255 @@ +using System.Web.Http; +using WebActivatorEx; +using WcfInterfaceServer; +using Swashbuckle.Application; + +[assembly: PreApplicationStartMethod(typeof(SwaggerConfig), "Register")] + +namespace WcfInterfaceServer +{ + public class SwaggerConfig + { + public static void Register() + { + var thisAssembly = typeof(SwaggerConfig).Assembly; + + GlobalConfiguration.Configuration + .EnableSwagger(c => + { + // By default, the service root url is inferred from the request used to access the docs. + // However, there may be situations (e.g. proxy and load-balanced environments) where this does not + // resolve correctly. You can workaround this by providing your own code to determine the root URL. + // + //c.RootUrl(req => GetRootUrlFromAppConfig()); + + // If schemes are not explicitly provided in a Swagger 2.0 document, then the scheme used to access + // the docs is taken as the default. If your API supports multiple schemes and you want to be explicit + // about them, you can use the "Schemes" option as shown below. + // + //c.Schemes(new[] { "http", "https" }); + + // Use "SingleApiVersion" to describe a single version API. Swagger 2.0 includes an "Info" object to + // hold additional metadata for an API. Version and title are required but you can also provide + // additional fields by chaining methods off SingleApiVersion. + // + c.SingleApiVersion("v1", "SDWebApi"); + + // If you want the output Swagger docs to be indented properly, enable the "PrettyPrint" option. + // + //c.PrettyPrint(); + + // If your API has multiple versions, use "MultipleApiVersions" instead of "SingleApiVersion". + // In this case, you must provide a lambda that tells Swashbuckle which actions should be + // included in the docs for a given API version. Like "SingleApiVersion", each call to "Version" + // returns an "Info" builder so you can provide additional metadata per API version. + // + //c.MultipleApiVersions( + // (apiDesc, targetApiVersion) => ResolveVersionSupportByRouteConstraint(apiDesc, targetApiVersion), + // (vc) => + // { + // vc.Version("v2", "Swashbuckle Dummy API V2"); + // vc.Version("v1", "Swashbuckle Dummy API V1"); + // }); + + // You can use "BasicAuth", "ApiKey" or "OAuth2" options to describe security schemes for the API. + // See https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md for more details. + // NOTE: These only define the schemes and need to be coupled with a corresponding "security" property + // at the document or operation level to indicate which schemes are required for an operation. To do this, + // you'll need to implement a custom IDocumentFilter and/or IOperationFilter to set these properties + // according to your specific authorization implementation + // + //c.BasicAuth("basic") + // .Description("Basic HTTP Authentication"); + // + // NOTE: You must also configure 'EnableApiKeySupport' below in the SwaggerUI section + //c.ApiKey("apiKey") + // .Description("API Key Authentication") + // .Name("apiKey") + // .In("header"); + // + //c.OAuth2("oauth2") + // .Description("OAuth2 Implicit Grant") + // .Flow("implicit") + // .AuthorizationUrl("http://petstore.swagger.wordnik.com/api/oauth/dialog") + // //.TokenUrl("https://tempuri.org/token") + // .Scopes(scopes => + // { + // scopes.Add("read", "Read access to protected resources"); + // scopes.Add("write", "Write access to protected resources"); + // }); + + // Set this flag to omit descriptions for any actions decorated with the Obsolete attribute + //c.IgnoreObsoleteActions(); + + // Each operation be assigned one or more tags which are then used by consumers for various reasons. + // For example, the swagger-ui groups operations according to the first tag of each operation. + // By default, this will be controller name but you can use the "GroupActionsBy" option to + // override with any value. + // + //c.GroupActionsBy(apiDesc => apiDesc.HttpMethod.ToString()); + + // You can also specify a custom sort order for groups (as defined by "GroupActionsBy") to dictate + // the order in which operations are listed. For example, if the default grouping is in place + // (controller name) and you specify a descending alphabetic sort order, then actions from a + // ProductsController will be listed before those from a CustomersController. This is typically + // used to customize the order of groupings in the swagger-ui. + // + //c.OrderActionGroupsBy(new DescendingAlphabeticComparer()); + + // If you annotate Controllers and API Types with + // Xml comments (http://msdn.microsoft.com/en-us/library/b2s063f7(v=vs.110).aspx), you can incorporate + // those comments into the generated docs and UI. You can enable this by providing the path to one or + // more Xml comment files. + // + //c.IncludeXmlComments(GetXmlCommentsPath()); + + // Swashbuckle makes a best attempt at generating Swagger compliant JSON schemas for the various types + // exposed in your API. However, there may be occasions when more control of the output is needed. + // This is supported through the "MapType" and "SchemaFilter" options: + // + // Use the "MapType" option to override the Schema generation for a specific type. + // It should be noted that the resulting Schema will be placed "inline" for any applicable Operations. + // While Swagger 2.0 supports inline definitions for "all" Schema types, the swagger-ui tool does not. + // It expects "complex" Schemas to be defined separately and referenced. For this reason, you should only + // use the "MapType" option when the resulting Schema is a primitive or array type. If you need to alter a + // complex Schema, use a Schema filter. + // + //c.MapType(() => new Schema { type = "integer", format = "int32" }); + + // If you want to post-modify "complex" Schemas once they've been generated, across the board or for a + // specific type, you can wire up one or more Schema filters. + // + //c.SchemaFilter(); + + // In a Swagger 2.0 document, complex types are typically declared globally and referenced by unique + // Schema Id. By default, Swashbuckle does NOT use the full type name in Schema Ids. In most cases, this + // works well because it prevents the "implementation detail" of type namespaces from leaking into your + // Swagger docs and UI. However, if you have multiple types in your API with the same class name, you'll + // need to opt out of this behavior to avoid Schema Id conflicts. + // + //c.UseFullTypeNameInSchemaIds(); + + // Alternatively, you can provide your own custom strategy for inferring SchemaId's for + // describing "complex" types in your API. + // + //c.SchemaId(t => t.FullName.Contains('`') ? t.FullName.Substring(0, t.FullName.IndexOf('`')) : t.FullName); + + // Set this flag to omit schema property descriptions for any type properties decorated with the + // Obsolete attribute + //c.IgnoreObsoleteProperties(); + + // In accordance with the built in JsonSerializer, Swashbuckle will, by default, describe enums as integers. + // You can change the serializer behavior by configuring the StringToEnumConverter globally or for a given + // enum type. Swashbuckle will honor this change out-of-the-box. However, if you use a different + // approach to serialize enums as strings, you can also force Swashbuckle to describe them as strings. + // + //c.DescribeAllEnumsAsStrings(); + + // Similar to Schema filters, Swashbuckle also supports Operation and Document filters: + // + // Post-modify Operation descriptions once they've been generated by wiring up one or more + // Operation filters. + // + //c.OperationFilter(); + // + // If you've defined an OAuth2 flow as described above, you could use a custom filter + // to inspect some attribute on each action and infer which (if any) OAuth2 scopes are required + // to execute the operation + // + //c.OperationFilter(); + + // Post-modify the entire Swagger document by wiring up one or more Document filters. + // This gives full control to modify the final SwaggerDocument. You should have a good understanding of + // the Swagger 2.0 spec. - https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md + // before using this option. + // + //c.DocumentFilter(); + + // In contrast to WebApi, Swagger 2.0 does not include the query string component when mapping a URL + // to an action. As a result, Swashbuckle will raise an exception if it encounters multiple actions + // with the same path (sans query string) and HTTP method. You can workaround this by providing a + // custom strategy to pick a winner or merge the descriptions for the purposes of the Swagger docs + // + //c.ResolveConflictingActions(apiDescriptions => apiDescriptions.First()); + + // Wrap the default SwaggerGenerator with additional behavior (e.g. caching) or provide an + // alternative implementation for ISwaggerProvider with the CustomProvider option. + // + //c.CustomProvider((defaultProvider) => new CachingSwaggerProvider(defaultProvider)); + }) + .EnableSwaggerUi(c => + { + // Use the "DocumentTitle" option to change the Document title. + // Very helpful when you have multiple Swagger pages open, to tell them apart. + // + //c.DocumentTitle("My Swagger UI"); + + // Use the "InjectStylesheet" option to enrich the UI with one or more additional CSS stylesheets. + // The file must be included in your project as an "Embedded Resource", and then the resource's + // "Logical Name" is passed to the method as shown below. + // + //c.InjectStylesheet(containingAssembly, "Swashbuckle.Dummy.SwaggerExtensions.testStyles1.css"); + + // Use the "InjectJavaScript" option to invoke one or more custom JavaScripts after the swagger-ui + // has loaded. The file must be included in your project as an "Embedded Resource", and then the resource's + // "Logical Name" is passed to the method as shown above. + // + //c.InjectJavaScript(thisAssembly, "Swashbuckle.Dummy.SwaggerExtensions.testScript1.js"); + + // The swagger-ui renders boolean data types as a dropdown. By default, it provides "true" and "false" + // strings as the possible choices. You can use this option to change these to something else, + // for example 0 and 1. + // + //c.BooleanValues(new[] { "0", "1" }); + + // By default, swagger-ui will validate specs against swagger.io's online validator and display the result + // in a badge at the bottom of the page. Use these options to set a different validator URL or to disable the + // feature entirely. + //c.SetValidatorUrl("http://localhost/validator"); + //c.DisableValidator(); + + // Use this option to control how the Operation listing is displayed. + // It can be set to "None" (default), "List" (shows operations for each resource), + // or "Full" (fully expanded: shows operations and their details). + // + //c.DocExpansion(DocExpansion.List); + + // Specify which HTTP operations will have the 'Try it out!' option. An empty paramter list disables + // it for all operations. + // + //c.SupportedSubmitMethods("GET", "HEAD"); + + // Use the CustomAsset option to provide your own version of assets used in the swagger-ui. + // It's typically used to instruct Swashbuckle to return your version instead of the default + // when a request is made for "index.html". As with all custom content, the file must be included + // in your project as an "Embedded Resource", and then the resource's "Logical Name" is passed to + // the method as shown below. + // + //c.CustomAsset("index", containingAssembly, "YourWebApiProject.SwaggerExtensions.index.html"); + + // If your API has multiple versions and you've applied the MultipleApiVersions setting + // as described above, you can also enable a select box in the swagger-ui, that displays + // a discovery URL for each version. This provides a convenient way for users to browse documentation + // for different API versions. + // + //c.EnableDiscoveryUrlSelector(); + + // If your API supports the OAuth2 Implicit flow, and you've described it correctly, according to + // the Swagger 2.0 specification, you can enable UI support as shown below. + // + //c.EnableOAuth2Support( + // clientId: "test-client-id", + // clientSecret: null, + // realm: "test-realm", + // appName: "Swagger UI" + // //additionalQueryStringParams: new Dictionary() { { "foo", "bar" } } + //); + + // If your API supports ApiKey, you can override the default values. + // "apiKeyIn" can either be "query" or "header" + // + //c.EnableApiKeySupport("apiKey", "header"); + }); + } + } +} diff --git a/webapi/WindowsFormsApp1/DBFactory.dll.config b/webapi/WindowsFormsApp1/DBFactory.dll.config new file mode 100644 index 0000000..d457a02 --- /dev/null +++ b/webapi/WindowsFormsApp1/DBFactory.dll.config @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/webapi/WindowsFormsApp1/WebAPI.csproj b/webapi/WindowsFormsApp1/WebAPI.csproj index 189fc95..2dbfb4a 100644 --- a/webapi/WindowsFormsApp1/WebAPI.csproj +++ b/webapi/WindowsFormsApp1/WebAPI.csproj @@ -27,7 +27,7 @@ http://127.0.0.1:8888/ true publish.htm - 6 + 1 1.0.0.%2a false true @@ -70,19 +70,37 @@ verifydialog.ico + + ..\..\packages\Microsoft.Web.Infrastructure.1.0.0.0\lib\net40\Microsoft.Web.Infrastructure.dll + - ..\packages\Nancy.1.4.5\lib\net40\Nancy.dll + ..\..\packages\Nancy.1.4.5\lib\net40\Nancy.dll - ..\packages\Nancy.Hosting.Self.1.4.1\lib\net40\Nancy.Hosting.Self.dll + ..\..\packages\Nancy.Hosting.Self.1.4.1\lib\net40\Nancy.Hosting.Self.dll - ..\packages\Newtonsoft.Json.13.0.1\lib\net45\Newtonsoft.Json.dll + ..\..\packages\Newtonsoft.Json.13.0.3\lib\net45\Newtonsoft.Json.dll + + + ..\..\packages\Swashbuckle.Core.5.6.0\lib\net40\Swashbuckle.Core.dll + + + ..\..\packages\Microsoft.AspNet.WebApi.Client.4.0.20710.0\lib\net40\System.Net.Http.Formatting.dll + + + + + ..\..\packages\Microsoft.AspNet.WebApi.Core.4.0.20710.0\lib\net40\System.Web.Http.dll + + + ..\..\packages\Microsoft.AspNet.WebApi.WebHost.4.0.20710.0\lib\net40\System.Web.Http.WebHost.dll + @@ -92,9 +110,13 @@ + + ..\..\packages\WebActivatorEx.2.0\lib\net40\WebActivatorEx.dll + + True True @@ -132,6 +154,10 @@ Designer + + Designer + Always + SettingsSingleFileGenerator diff --git a/webapi/WindowsFormsApp1/packages.config b/webapi/WindowsFormsApp1/packages.config index cc4f0ac..bc1d7dd 100644 --- a/webapi/WindowsFormsApp1/packages.config +++ b/webapi/WindowsFormsApp1/packages.config @@ -1,6 +1,14 @@  - - - + + + + + + + + + + + \ No newline at end of file