问题 .NET核心 2.1控制台应用程序带HTTP客户工厂问题

Raysefo.

众所周知的成员
加入
2019年2月22日
消息
204
编程经验
10+
嗨,大家好,
我想实现一个预定的任务,该任务将每小时检查API并将福彩12选5走势图插入福彩12选5走势图库,如果福彩12选5走势图已在福彩12选5走势图库中不存在。我读了一些文章并用这个来了。我想知道你是否可以指导我将福彩12选5走势图插入一个SQL表中,如果它尚未在那里。 (顺便说一下,大多数可能我不会在我的代码中使用polly重试机制。)


Program.cs:
using System;
using System.IO;
using System.Net.Http;
using System.Threading.Tasks;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Polly;
using Polly.Extensions.Http;
using Polly.Registry;

namespace TrendyolGamePurchase
{
    class Program
    {
        static async Task Main(string[] args)
        {
            //Read App Settings
            var build = new ConfigurationBuilder();
            BuildConfig(build);

            var config = build.Build();
          
            Console.Write(config["ConnectionStrings:Development"]);
          
            //Polly Retry
            var builder = new HostBuilder()
                .ConfigureServices((hostContext, services) =>
                {
                    IPolicyRegistry<string> registry = services.AddPolicyRegistry();

                    //First Policy
                    IAsyncPolicy<HttpResponseMessage> httpWaitAndRetryPolicy =
                        Policy.HandleResult<HttpResponseMessage>(r => !r.IsSuccessStatusCode)
                            .WaitAndRetryAsync(3, retryAttempt => TimeSpan.FromSeconds(Math.Pow(3, retryAttempt)));

                    registry.Add("SimpleWaitAndRetryPolicy", httpWaitAndRetryPolicy);

                    //Second Policy
                    IAsyncPolicy<HttpResponseMessage> noOpPolicy = Policy.NoOpAsync()
                        .AsAsyncPolicy<HttpResponseMessage>();

                    registry.Add("NoOpPolicy", noOpPolicy);

                    //Third Policy
                    var timeOutPolicy = Policy.TimeoutAsync(TimeSpan.FromSeconds(10));
                        
                    registry.Add("timeOutPolicy", timeOutPolicy);

                    services.AddHttpClient("TestClient", client =>
                    {
                        client.BaseAddress = new Uri("http://test//api/v2/web/game/purchase");
                        client.DefaultRequestHeaders.Add("Accept", "application/json");
                    }).AddPolicyHandlerFromRegistry((policyRegistry, httpRequestMessage) =>
                    {
                        if (httpRequestMessage.Method == HttpMethod.Post)
                        {
                            Console.WriteLine(DateTime.Now);
                            return policyRegistry.Get<IAsyncPolicy<HttpResponseMessage>>("SimpleWaitAndRetryPolicy");
                        }
                        return policyRegistry.Get<IAsyncPolicy<HttpResponseMessage>>("NoOpPolicy");
                    });

                    services.AddSingleton<IHostedService, BusinessService>();
                });

            await builder.RunConsoleAsync();
        }
        static void BuildConfig(IConfigurationBuilder builder)
        {
            builder.SetBasePath(Directory.GetCurrentDirectory())
                .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true);


        }
    }
}

BusinessService.cs:
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Hosting;

namespace TrendyolGamePurchase
{
    public class BusinessService : IHostedService
    {
        private IHttpClientFactory _httpClientFactory;
        public BusinessService(IHttpClientFactory httpClientFactory)
        {
            _httpClientFactory = httpClientFactory;
        }

        public async Task StartAsync(CancellationToken cancellationToken)
        {
            await MakeTestRequestsToRemoteService();
        }

        public async Task MakeTestRequestsToRemoteService()
        {
            HttpClient httpClient = _httpClientFactory.CreateClient("TestClient");

            var authenticationBytes = Encoding.ASCII.GetBytes("Test:12345");

            httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic",
                Convert.ToBase64String(authenticationBytes));
            httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

            var content = new FormUrlEncodedContent(new[]
            {
                new KeyValuePair<string, string>("productCode", "1"),
                new KeyValuePair<string, string>("quantity","1"),
                new KeyValuePair<string, string>("shopNo","Palas"),
                new KeyValuePair<string, string>("safeNo","Palas"),
                new KeyValuePair<string, string>("cashierNo","Palas")

            });
            var response = await httpClient.PostAsync("http://test//api/v2/web/game/purchase", content);
            

        }

        public Task StopAsync(CancellationToken cancellationToken)
        {
            return Task.CompletedTask;
        }
    }
}
 

Raysefo.

众所周知的成员
加入
2019年2月22日
消息
204
编程经验
10+
以及 @skydiver mentioned I can't set id autoincrement because I am getting it from the API. Not sure but most probably id will be unique. But not to take chances, I will also use orderDate in the keys. There is this customerId so it won't be a problem if two different user makes orders at the same time.
Now I think I have to create a method in the BusinessService.cs to implement this insert operation.
 

跳伞运动员

工作人员
加入
2019年4月6日
消息
2,619
地点
切萨皮克,va.
编程经验
10+
我的天啊!所以你已经在这个项目上工作了几个月,并没有将东西写入福彩12选5走势图库?如果公司/客户/产品正在基于交易数量的利润,并且您不保留自己的交易记录通过API,那么这是否意味着您最初只是采取API所有者的单词正如所得税所在的那样是什么?

无论如何,最好开始学习一些ADO.NET。我和 @sheepings.)建议您将从实体框架转向,特别是您说您更舒适地使用Direct SQL。不幸的是,许多当前文献似乎默认到实体框架。

 

sh

众所周知的成员
加入
2018年9月5日
消息
1,982
编程经验
10+
这就是为什么我对我之前的帖子说:
我假设他正在查询API并将福彩12选5走势图保存到他自己/外部福彩12选5走势图库?
我在假设,但我也暗指了这一点。如果OP不使用自己/或他的客户端的福彩12选5走势图库将返回的福彩12选5走势图从此质疑的API存储,那么你如何知道通过您的客户正在开发的应用程序进行了多少订单?

您最好希望您的客户在以后对您诉诸于您自己的无能为力,有关创建此应用程序。从我从这个线程和过去的线程中收集的东西,OP还使用API​​作为福彩12选5走势图传输的源,同时不会对他的客户保持任何外部记录,以通过该系统发出多少订单,他正在建立起来。

希望,我的缘故是错的。

关于整个EF使用情况,我认为你应该读到这一点: iamtimcorey |我应该使用实体框架

@ raysefo. 从您在P2 /#21上说的 - 从API收到的福彩12选5走势图应该被存储到外部服务器中,以获取客户端记录保留。我的我的...
 

Raysefo.

众所周知的成员
加入
2019年2月22日
消息
204
编程经验
10+
如果您有任何建议,可以使其更可维护,可测试,强大和动态?

C#:
class Program
    {
        static async Task Main(string[] args)
        {
                          
            var builder = new HostBuilder()
                .ConfigureServices((hostContext, services) =>
                {
                    //Setting up API Client
                    services.AddHttpClient("OrdersClient", client =>
                    {
                        client.BaseAddress =
                            new Uri("//test/282675/orders?status=Created");

                        client.DefaultRequestHeaders.Add("Accept", "application/json");
                    });

                    services.AddSingleton<IHostedService, BusinessService>();

                    //Setting up app settings configuration
                    var config = LoadConfiguration();   
                    services.AddSingleton(config);
                });

            await builder.RunConsoleAsync();
      
        public static IConfiguration LoadConfiguration()
        {
            var builder = new ConfigurationBuilder()
                .SetBasePath(Directory.GetCurrentDirectory())
                .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true);

            return builder.Build();
        }
    }

public class BusinessService : IHostedService
    {
        private IHttpClientFactory _httpClientFactory;
        private readonly IHostApplicationLifetime _applicationLifetime;
        private IConfiguration _configuration;
        public BusinessService(IHttpClientFactory httpClientFactory, IHostApplicationLifetime applicationLifetime, IConfiguration configuration)
        {
            _httpClientFactory = httpClientFactory;
            _applicationLifetime = applicationLifetime;
            _configuration = configuration;
        }

        public async Task StartAsync(CancellationToken cancellationToken)
        {
            await MakeRequestsToRemoteService();
            //Stop Application
            _applicationLifetime.StopApplication();
        }

        public async Task MakeRequestsToRemoteService()
        {
            HttpClient httpClient = _httpClientFactory.CreateClient("OrdersClient");

            var authenticationBytes = Encoding.ASCII.GetBytes("test:1234");

            httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic",
                Convert.ToBase64String(authenticationBytes));
            httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

            var response = await httpClient.GetAsync("//test/282675/orders?startDate=1612126800000");
            Console.WriteLine(DateTime.Now);

            if (response.IsSuccessStatusCode)
            {
                Root orders = await response.Content.ReadAsAsync<Root>();

                if (orders.Content.Count > 0)
                {
                    foreach (var content in orders.Content)
                    {
                        Console.Write(content.CustomerId + " " + content.CustomerFirstName + " " + content.CustomerLastName + " " + content.CustomerEmail +" " + content.TotalPrice + " "+ content.InvoiceAddress.Phone + " " + content.Lines[0].ProductCode + " " +content.Lines[0].ProductName );
                        InsertData(content);
                    }
                }

            }
            
            
        }

        public void InsertData(Content content)
        {
          
            
            string connString = _configuration["ConnectionStrings:Development"];
            using (SqlConnection sqlConnection = new SqlConnection(connString))
            {
                sqlConnection.Open();

                using (SqlCommand command = new SqlCommand())
                {
                    command.Connection = sqlConnection;
                    string sql = @"insert into Orders (id, customerId, firstName, lastName, phone, productCode, productName, price, orderDate, status) values (@id, @customerId, @firstName, @lastName, @phone, @productCode, @productName, @price, @orderDate, @status)";
                    command.CommandText = sql;
                    command.Parameters.Clear();
                    
                    try
                    {
                        command.Parameters.Add("id", SqlDbType.BigInt).Value = content.Id;
                        command.Parameters.Add("customerId", SqlDbType.Int).Value = content.CustomerId;
                        command.Parameters.Add("firstName", SqlDbType.VarChar).Value = content.CustomerFirstName;
                        command.Parameters.Add("lastName", SqlDbType.VarChar).Value = content.CustomerLastName;
                        command.Parameters.Add("phone", SqlDbType.VarChar).Value = content.InvoiceAddress.Phone;
                        command.Parameters.Add("productCode", SqlDbType.Int).Value = content.Lines[0].ProductCode;
                        command.Parameters.Add("productName", SqlDbType.VarChar).Value = content.Lines[0].ProductName;
                        command.Parameters.Add("price", SqlDbType.Float).Value = content.TotalPrice;
                        command.Parameters.Add("orderDate", SqlDbType.BigInt).Value = content.OrderDate;
                        command.Parameters.Add("status", SqlDbType.TinyInt).Value = 1; //Retrieved

                        command.ExecuteNonQuery();
                    }
                    catch (SqlException exception)
                    {
                        if (exception.Number == 2627) // Cannot insert duplicate key row in object error
                        {
                            Console.WriteLine("Duplicates...");
                        }
                        else
                            throw; // Throw exception if this exception is unexpected
                    }
                }
            }
        }

        public Task StopAsync(CancellationToken cancellationToken)
        {
            return Task.CompletedTask;
        }
    }
 

跳伞运动员

工作人员
加入
2019年4月6日
消息
2,619
地点
切萨皮克,va.
编程经验
10+
你为什么在53行停止申请?

我不清楚第3-34行可能会编译。

没有必要行73.如果有零项目,Foreach将不会迭代。

第120行:应该避免魔术数字。

There is no need for liken 101. It's a brand new SqlCommand instance. Why would you need to clear out the Parameters list when it's already empty.
 
最佳 底部