简体   繁体   English

asp.net core 3.1 上的 Json 请求

[英]Json request on asp.net core 3.1

I trie to pass my item Reach_DeclarationBc我试图通过我的项目 Reach_DeclarationBc

    public class Reach_DeclarationBc
    {
        public int ArticleId { get; set; }
        public DateTime DateDeclaration { get; set; }
    }

I use this code for call my api我使用此代码调用我的 api

var client = new HttpClient();

client.BaseAddress = new Uri("http://localhost:3001/");
Reach_DeclarationBc reach_DeclarationBc = new Reach_DeclarationBc
{
    ArticleId = 129,
    DateDeclaration = DateTime.Now
};

Reach_DeclarationBc result = await client.PostJsonAsync<Reach_DeclarationBc>("http://localhost:3009/reach", reach_DeclarationBc);

But a this line this give me an error但是这条线这给了我一个错误

Reach_DeclarationBc result = await client.PostJsonAsync<Reach_DeclarationBc>("http://localhost:3009/reach", reach_DeclarationBc);

The error is : "TypeLoadException: Could not load type 'Microsoft.JSInterop.Json' from assembly 'Microsoft.JSInterop, Version=3.1.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60'."错误是:“TypeLoadException:无法从程序集 'Microsoft.JSInterop,Version=3.1.0.0,Culture=neutral,PublicKeyToken=adb9793829ddae60' 中加载类型 'Microsoft.JSInterop.Json'。”

The using in my class is在我的课上使用的是

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Projet_Airbus.Data;
using Projet_Airbus.Models;
using Projet_Airbus.Models.Declaration;
using Microsoft.AspNetCore.Blazor;  
using System.Net.Http;  

For solve i tri to use asp.net core 3.1 but this not work为了解决我尝试使用asp.net core 3.1,但这不起作用

This is how I usually do it.这就是我通常的做法。

  1. I inject a singleton HttpClient and logger with a dependency injector like Ninject .我用Ninject这样的依赖注入器注入了一个 单例 HttpClient和记录器。
  2. I make a generic SendAsync which can handle PUT/DELETE/POST/GET.我制作了一个通用的SendAsync ,它可以处理 PUT/DELETE/POST/GET。
  3. I make ApiResponse class that contains the properties I'm interested in.我创建了包含我感兴趣的属性的ApiResponse类。
  4. I create a Request class ( InitRequest ) that I use for the request.我创建了一个Request类 ( InitRequest )。
  5. I create a Response class ( InitResponse ) that I use for the response.我创建了一个用于Response类 ( InitResponse )。
  6. I have TimeOutInMs to set the time out for the api call.我有TimeOutInMs来设置 api 调用的TimeOutInMs时间。
  7. I have a logger that logs error.我有一个logger错误的logger
    using System;
    using System.Net;
    using System.Net.Http;
    using System.Net.Http.Headers;
    using System.Text;
    using System.Threading;
    using System.Threading.Tasks;
    using System.Web.Mvc;
    using Newtonsoft.Json;

    public class HomeController : Controller
    {
        private readonly WebApi _webApi;
        //Inject singleton httpclient and logger
        public HomeController(HttpClient httpClient, ILogger logger)
        {
            _webApi = new WebApi(httpClient, logger);
            _webApi.BaseAddress = "https://www.webapi.com/";
            _webApi.TimeOutInMs = 2000;
        }

        public async Task<ActionResult> Index()
        {
            //You might want to move the web api call to a service class
            var method = "init";
            var request = new InitRequest
            {
                Id = 1,
                Name = "Bob"
            };

            var response = await _webApi.SendAsync<InitResponse>(method, request, HttpMethod.Post);
            if (response.StatusCode == HttpStatusCode.OK)
            {
                var viewModel = response.Data.ToIndexViewModel();
            }
            else
            {
                //Handle Error
            }

            return View(viewModel);
        }
    }

    public class IndexViewModel
    {
        public string Name { get; set; }
        public string Address { get; set; }
    }

    public static class ModelMapper
    {
        public static IndexViewModel ToIndexViewModel(this InitResponse response)
        {
            return new IndexViewModel
            {
                Name = response.Name,
                Address = response.Address
            };
        }
    }

    public class InitRequest
    {
        public int Id { get; set; }
        public string Name { get; set; }
    }

    public class InitResponse
    {
        public string Name { get; set; }
        public string Address { get; set; }
    }

    public class WebApi
    {

        private readonly HttpClient _httpClient;
        private readonly ILogger _logger;
        public Uri BaseAddress { get; set; }
        public int TimeOutInMs { get; set; }

        public WebApi(HttpClient httpClient, ILogger logger)
        {
            _logger = logger ?? throw new Exception($"Missing constructor ceference - {nameof(logger)} can not be null!");
            _httpClient = httpClient ?? throw new Exception($"Missing constructor ceference - {nameof(httpClient)} can not be null!");
        }

        public async Task<ApiResponse<TOut>> SendAsync<TOut>(string method, object param, HttpMethod httpMethod)
        {
            if (string.IsNullOrWhiteSpace(BaseAddress.ToString()))
                throw new Exception($"{nameof(BaseAddress)} can not be null or empty.");


            if (string.IsNullOrWhiteSpace(method))
                throw new Exception($"{nameof(method)} can not be null or empty.");

            var paramListForLog = JsonConvert.SerializeObject(param);

            //Set timeout
            if (TimeOutInMs <= 0)
            {
                TimeOutInMs = (int)TimeSpan.FromSeconds(100.0).TotalMilliseconds;
            }

            var cts = new CancellationTokenSource();
            cts.CancelAfter(TimeSpan.FromMilliseconds(TimeOutInMs));

            var cancellationToken = cts.Token;

            var url = new Uri($"{BaseAddress}{method}", UriKind.Absolute);

            try
            {

                HttpResponseMessage response;
                using (var request = new HttpRequestMessage(httpMethod, url))
                {
                    //Add content
                    if (param != null)
                    {
                        var content = JsonConvert.SerializeObject(param);
                        request.Content = new StringContent(content, Encoding.UTF8, "application/json");
                    }
                    //Add headers
                    request.Headers.Accept.Clear();
                    request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

                    _logger.Info($"Calling {httpMethod} for {url}", paramListForLog);
                    //Send the request
                    response = await _httpClient.SendAsync(request, cancellationToken);
                }

                //If success
                if (response.IsSuccessStatusCode)
                {
                    _logger.Info($"Successfully called {httpMethod} for {url}", paramListForLog);
                    var data = await response.Content.ReadAsAsync<TOut>(cancellationToken);

                    return new ApiResponse<TOut>
                    {
                        StatusCode = response.StatusCode,
                        Data = data
                    };
                }

                //If failure
                var error = await response.Content.ReadAsStringAsync();
                _logger.Error($"An error occured calling {httpMethod} for {url}. Error was {error}", paramListForLog);
                return new ApiResponse<TOut>
                {
                    StatusCode = response.StatusCode,
                    Message = error
                };
            }
            //If timeout
            catch (OperationCanceledException ex)
            {
                var message = cancellationToken.IsCancellationRequested ?
                    $"Request timed out after {TimeOutInMs} ms occured calling {httpMethod} for {url}. Error was: {ex.Message}" :
                    $"An error occured calling {httpMethod} for {url}. Error was: {ex.Message}";

                var webEx = new Exception(message, ex);
                _logger.Error(webEx, webEx.Message, paramListForLog);

                return new ApiResponse<TOut>
                {
                    StatusCode = HttpStatusCode.RequestTimeout,
                    Message = message
                };
            }
            //If unknown error
            catch (Exception ex)
            {
                var webEx = new Exception($"An error occured calling {httpMethod} for {url}. Error was: {ex.Message}", ex);
                _logger.Error(webEx, webEx.Message, paramListForLog);
                throw webEx;
            }
        }
    }
    public interface ILogger
    {
        void Info(string message, string param);
        void Error(string message, string param);
        void Error(Exception e, string message, string param);
    }

    public class ApiResponse<T>
    {
        public HttpStatusCode StatusCode { get; set; }
        public string Message { get; set; }
        public T Data { get; set; }
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM