asp.net 如何从streamReader的responseBody中获取特定属性的计数

h43kikqp  于 2023-06-25  发布在  .NET
关注(0)|答案(1)|浏览(111)

你好,我想在数据库中存储特定数据的计数,这是一个custome中间件存储日志在数据库中,控制器中的每一个动作返回一个responseResultObkect其中有一些属性的当然结果,它应该得到该对象的结果属性,并给出结果的计数,我不知道我可以解释好或不,但我分享的代码,我希望你能帮助我,谢谢很多。

public ChallengeMiddleware(RequestDelegate RequestDelegate)
        {
            if (RequestDelegate == null)
            {
                throw new ArgumentNullException(nameof(RequestDelegate)
                    , nameof(RequestDelegate) + " is required");
            }

            _request = RequestDelegate;
        }
        public async Task InvokeAsync(HttpContext Context, ILogService logService,
            IHttpContextAccessor httpContextAccessor, IExceptionService2 exceptionService)
        {
            Stream originalBody = Context.Response.Body;
            ServiceLog logMetadata = await LogRequest(Context);
            try
            {
                if (Context == null)
                {
                    throw new ArgumentNullException(nameof(Context)
                        , nameof(Context) + " is required");
                }

                //****************************** Response *************************************

                using (var memStream = new MemoryStream())
                {
                    string errorMsg = "";

                    //Stream originalBody = Context.Response.Body;
                    Context.Response.Body = memStream;

                    await _request(Context);
                    var controllerName = Context.GetRouteData().Values["controller"];
                    var actionName = Context.GetRouteData().Values["action"];
                    if (controllerName != null)
                    {
                        logMetadata.ControllerName = controllerName.ToString();
                    }
                    if (actionName != null)
                    {
                        logMetadata.ActionName = actionName.ToString();
                    }
                    memStream.Position = 0;
                    string responseBody = new StreamReader(memStream).ReadToEnd();
                    memStream.Position = 0;
                    await memStream.CopyToAsync(originalBody);

                    if (Context.Response.StatusCode != (int)HttpStatusCode.OK)
                    {
                        switch (Context.Response.StatusCode)
                        {
                            case (int)HttpStatusCode.Unauthorized:
                                errorMsg = "دسترسی شما مجاز نمیباشد";
                                break;
                            case (int)HttpStatusCode.BadRequest:
                                errorMsg = "درخواست شما قابل اجرا نیست";
                                break;
                            case (int)HttpStatusCode.NotFound:
                                errorMsg = "درخواست ارسالی شما معتبر نیست";
                                break;
                            case (int)HttpStatusCode.InternalServerError:
                                errorMsg = "درخواست شما با خطا مواجهه شده است";
                                break;
                        }
                        Context.Response.Body = originalBody;
                       
                    }

                    var routeData = httpContextAccessor.HttpContext.GetRouteData();
                    var apiKey = routeData.Values["ApiKey"];
                    if (apiKey != null)
                    {
                        var apiKeyString = apiKey.ToString();
                        logMetadata.requestContent = apiKeyString;
                    }

                    if (!String.IsNullOrEmpty(responseBody))
                        try
                        {
                           
                            dynamic objectResult = JsonConvert.DeserializeObject(responseBody);
                            var count = 0;
                            
                            foreach (var item in objectResult)
                            {
                                var result = item.First.result;
                                if(result!= null)
                                    count++;
                            }
                            var count2 = count;
                            

                        }
                        catch (System.Exception e)
                        {
                            logMetadata.responseOtherContent = responseBody;
                           
                        }
                }

                logMetadata.responseContentType = Context.Response.ContentType;
                logMetadata.responseDate = DateTime.SpecifyKind(DateTime.Now, DateTimeKind.Utc);
                logMetadata.responseStatusCode = (HttpStatusCode)Context.Response.StatusCode;
                logService.addAddServiceLog(logMetadata);

                //****************************** End Response *************************************
            }
            catch (Exception e)
            {
                Context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
                Context.Response.Body = originalBody;
                logMetadata.responseResultObject = WriteErrorObjectResultResponse(Context, e.Message);
                logMetadata.responseContentType = Context.Response.ContentType;
                logMetadata.responseDate = DateTime.SpecifyKind(DateTime.Now, DateTimeKind.Utc);
                logMetadata.responseStatusCode = HttpStatusCode.InternalServerError;
                logService.addAddServiceLog(logMetadata);
            }
        }

例如,这是我的登录控制器:

[HttpPost("Login")]
        public async Task<IActionResult> Login(DTOUserForLogin userForLoginDTO)
        {
            // Check if username exists and if the username exists check if the username/ password combination is valid
            var userFromRepo = await _Service.Login(userForLoginDTO.UserName.ToLower(), userForLoginDTO.Password);

            // if username does not exist or username/password combination invalid break out of login process & return error
            if (userFromRepo == null)
                return await UserNotExist();
            else
            if (!userFromRepo.Active)
                return await UserNotActive();

            DTOUserDetails usersToReturn = new DTOUserDetails()
            {
                Created = userFromRepo.Created,
                Id = userFromRepo.ID,
                LastActive = userFromRepo.LastActive,
                Owner = userFromRepo.Owner,
                UserName = userFromRepo.UserName
            };

            // Fill Lazy Load Current User With All Childs Entity
            // CurrentUser = await _userService.GetByID(userFromRepo.ID, DefaultIncludes.UserDefaultIncludes);
            string token = new TokenService(_Config).CreateToken(userFromRepo);

            DTOUserWithToken dTOUserWithToken = new DTOUserWithToken();
            dTOUserWithToken.Token = token;
            dTOUserWithToken.User = usersToReturn;
            // send token
            resultObject = new DTOResultObject(dTOUserWithToken);
            //return new OkObjectResult(new List<long> { 1, 2 });
            return new OkObjectResult(resultObject);
        }

这是我的objectresult类:

public class DTOResultObject
    {
        public DTOResultObject()
        {

        }
        public DTOResultObject(string singleMessage)
        {
            if (!string.IsNullOrEmpty(singleMessage))
            {
                serverErrors = new List<DTOError>();
                //serverErrors.Add(new DTOError() { Message = singleMessage });
            }
        }
        public DTOResultObject(object _Result)
        {
            Result = JsonConvert.SerializeObject(_Result);
        }
        public int Id { get; set; }
        public int logId { get; set; }
        [JsonIgnore]
        public ServiceLog log { get; set; }
        [JsonIgnore] 
        public List<DTOError> serverErrors { get; set; }
        public string Result { get; set; }
    }

例如,我的登录控制器如果登录成功,返回一个DtoObjectResult,它的result属性中有一个json web token,所以我们有一个result属性,我想将数据库中的数字1保存为日志表中的result count,这段challengeMiddleWare代码:

responseBody = responseBody.Replace(@"\", " ");
 
                            dynamic objectResult = JsonConvert.DeserializeObject(responseBody);
                            var count = 0;
                            
                            foreach (var item in objectResult)
                            {
                                var result = item.First.result;
                                if(result!= null)
                                    count++;
                            }
                            var count2 = count;

当我跟踪代码时,例如当我调用:“Register“操作,该操作将返回已注册用户的数据、以下值:objectResult变量为:

{{
  "id": 0,
  "logId": 0,
  "log": null,
  "serverErrors": null,
  "result": "[{\"Id\":27,\"Owner\":\"admin9\",\"UserName\":\"admin9\",\"Created\":\"2023-06-07T17:11:17.2434468+03:30\",\"LastActive\":\"0001-01-01T00:00:00\"}]"
}}

我想要count变量的数字1,因为我们只有一个结果为“result”部分,但不幸的是,它给了我数字5,意味着DTOResultObject类中的属性的计数,如id,logId,log,serverErrors和result属性,但我想要result属性中的结果的数字,你能帮我做什么吗?谢谢。

bttbmeg0

bttbmeg01#

你可能想知道result属性中有多少组json数据,你可以单独处理result

dynamic objectResult = JsonConvert.DeserializeObject(responseBody);
var count = 0;
var objResult = JsonConvert.SerializeObject(objectResult.result).Trim('\"').Replace(@"\", " ");
var list = JsonConvert.DeserializeObject<List<object>>(objResult);

foreach (var item in list)
{
    var result = item;
    if (result != null)
        count++;
}
var count2 = count;

测试结果:

相关问题