服务器花费太多时间在ASP.NET Web API中发送响应 - 超时错误

时间:2015-04-23 09:17:51

标签: c# regex asp.net-mvc asp.net-web-api server-response

我已经创建了一个在服务器上工作的Web API应用程序。在客户端,测试我有Android应用程序。 这很简单。用户输入用户名和密码,并使用另外两个字符串DeviceId和DeviceName发送它们。 用户通过已定义的服务进行验证,如果一切顺利,则会发生以下情况:

  1. 创建用户并将其保存在数据库中。
  2. 信息电子邮件将发送给用户。
  3. 访问令牌将返回给客户端。
  4. 但是在对我的代码进行一些更改之后,来自服务器的响应开始花费太长时间,而对于移动用户来说,超时发生的时间太频繁了。

    我注意到在我添加了一段特定代码后,超时开始发生了:

    Regex rgx = new Regex("[^a-zA-Z0-9 -]");
    string deviceId = rgx.Replace(model.DeviceId, "");
    

    此部分用于修剪DeviceID字符串中的所有非字母数字字符。这很重要,因为在添加此代码之前,如果用户在此变量中使用了斜杠或反斜杠,则会出现与JSON相关的错误。

    所以我的问题是:Regex类及其方法是否可能在服务器上造成一些混乱并使服务器响应时间过长?

    如果有任何帮助,这是有问题的电话代码:

    [Route("registration/request")]
    public async Task<HttpResponseMessage> RegistrationRequest(Registration model)
    {
        try
        {
            MatrixLogManager.Info("Starting token creating.");
    
            var request = HttpContext.Current.Request;
            var tokenServiceUrl = request.Url.GetLeftPart(UriPartial.Authority) + request.ApplicationPath + "/Token";
    
            MatrixLogManager.Info("Checking if model is valid.");
            if (!ModelState.IsValid)
            {
                return Request.CreateResponse(BadRequest(ModelState));
            }
            using (MatrixServiceLayerLogin login = new MatrixServiceLayerLogin())
            {
                if (login.LoginUser(model.UserName, model.Password, true, true))
                {
                    var personId = login.GetPersonId();
    
                    MatrixLogManager.Debug("User " + model.UserName + " successfully logged in on MatrixSTS.");
                    try
                    {
                        using (var authRepo = new AuthRepository())
                        {
                            MatrixLogManager.Info("Changing deviceID format.");
                            Regex rgx = new Regex("[^a-zA-Z0-9 -]");
                            model.DeviceId = rgx.Replace(model.DeviceId, "");
                            MatrixLogManager.Debug(model.DeviceId);
                            MatrixLogManager.Debug("Saving user: " + model.DeviceId);
                            ApplicationUser appUser = new UserFactory().CreateApplicationUser(model, personId);
    
                            IdentityResult result = await authRepo.RegisterUser(appUser);
                            EMailService.SendEmail(appUser);
                            IHttpActionResult errorResult = GetErrorResult(result);
    
                            MatrixLogManager.Debug("Saved user: " + model.DeviceId);
                            if (errorResult != null)
                            {
                                return Request.CreateResponse(errorResult);
                            }
    
                            using (var client = new HttpClient())
                            {
                                var requestParams = new List<KeyValuePair<string, string>>
                                            {
                                                new KeyValuePair<string, string>("grant_type", "password"),
                                                new KeyValuePair<string, string>("username", appUser.UserName),
                                                new KeyValuePair<string, string>("password", "0000")
                                            };
    
                                var requestParamsFormUrlEncoded = new FormUrlEncodedContent(requestParams);
                                var tokenServiceResponse = await client.PostAsync(tokenServiceUrl, requestParamsFormUrlEncoded);
                                var responseString = await tokenServiceResponse.Content.ReadAsStringAsync();
                                var responseCode = tokenServiceResponse.StatusCode;
                                var responseMsg = new HttpResponseMessage(responseCode)
                                {
                                    Content = new StringContent(responseString, Encoding.UTF8, "application/json")
                                };
    
                                responseMsg.Headers.Add("PSK", appUser.PSK);
                                return responseMsg;
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        MatrixLogManager.Error("Error: ", ex);
                        throw ex;
                    }
                }
                else
                {
                    return Request.CreateErrorResponse(HttpStatusCode.Unauthorized, "Invalid username or password.");
                }
            }
        }
        catch (Exception ex)
        {
            MatrixLogManager.Error(string.Format("Error while trying registring user: Exception = {0} InnerException {1}", ex.Message, ex.InnerException.Message));
            throw;
        }
    }
    

    P.S。还有一件事。当我在我的机器上测试这个代码时,本地响应时间不是很长,而且一切顺利。问题是只有当这个代码发布到服务器时才会发生,并且它发生的次数很多。

1 个答案:

答案 0 :(得分:0)

我在这里看到两个问题:

Regex rgx = new Regex("[^a-zA-Z0-9 -]");
model.DeviceId = rgx.Replace(model.DeviceId, "");

首先,通过使用正则表达式构造函数,您每次应用它时都会强制系统创建一个新的Regex对象。如果您使用其中一种静态方法,系统会在您第一次使用它时自动缓存Regex对象。或者您可以提前构建正则表达式并将其存储在静态变量中。

其次,您要一次更换一个不需要的字符,这是非常低效的。在正则表达式的末尾添加+,以便一次匹配不需要的字符的整个序列。

model.DeviceId = Regex.Replace(model.DeviceId, "[^a-zA-Z0-9 -]+", "");