Troubleshooting 11205 Errors

Kmcnet 696 Reputation points
2022-07-21T22:38:29.207+00:00

Hello everyone and thanks for the help in advance. I have a web application that is an endpoint for Twilio phone api to make calls to. The endpoint makes three SQL database calls using EntityFramework Core. The server is running Windows Server 2022. The database calls are really not terribly intensive and I will be happy to post those, but am trying to start off simply. The calling application to my api has a timeout of 10 seconds which to me is inconceivable this is happening. But I need to start troubleshooting this problem and really don't know how to get started (that includes understanding IIS logs). Any help would be appreciated.

ASP.NET Core
ASP.NET Core
A set of technologies in the .NET Framework for building web applications and XML web services.
4,238 questions
{count} votes

10 answers

Sort by: Newest
  1. Kmcnet 696 Reputation points
    2022-08-21T21:20:49.663+00:00

    OK, circling back to this thread, because I really do want to understand the concepts in this thread. But at the end of the day, none of them worked. Async, dependency injection, repository pattern etc., but the controller still times out in production on occasional incoming calls. Ultimately, in order to get the application working reliably, I ended up putting the incoming call on hold, then processing the call information, then acting on the call in a separate application. Not ideal, but getting the job done. Now, to return back to the original post, I did set up each of the methods being called as async, however, that actually seemed to exacerbate the problem. My question regarding the code samples was implementing the dependency injection I'm using .Net 6 MVC. Within Program.cs, I added:

    builder.Services.AddDbContext<myDbContext>();  
    

    But I am confused as to the best way to instantiate this, i.e. do I create an instance within the controller and pass it to the methods?

    Since I am not setting my code up for unit testing, I obviously need to restructure it, but how do I test this in a production environment?

    0 comments No comments

  2. AgaveJoe 26,166 Reputation points
    2022-07-28T17:20:02.993+00:00

    I really do want to learn this. But I do have a few questions. First, what is gained by using dependency injection as opposed to a using? Does it increase performance?

    It breaks dependency on your classes and makes testing much easier. Plus you get to configure service scope in one location. For example, the DbContext can be scoped to the request. One DbContext is created per request. Since the DbContext can be large, this can increase performance.

    Second, and more importantly, if you await the tasks prior to returning the response, am I not back to creating the possible bottleneck rather than spinning off tasks that can be executed without locking the thread?

    Your design does not work how you think. Your InboundVoice() method is synchronous.

    It would be better to make all three processes async then wait all. The total processing time is the time it takes the longest process to run. This type of information is covered in the documentation in my last post.

    AS far as testing the code, everything works fine without any of the database call, so the Twilio bits work fine.

    Sound like a bottleneck with the database. But, after reading the Twilio docs I'm not sure.

    0 comments No comments

  3. AgaveJoe 26,166 Reputation points
    2022-07-29T18:18:20.957+00:00

    Does not work when the signature for the method requires a myDbContext:

    It sounds like you did not register the DbContext as a service when the application starts. The following line of code registers a DbContext in a .NET 6 program.cs file.

    builder.Services.AddDbContext<MvcSqlLiteContext>(options =>  
           options.UseSqlite(builder.Configuration.GetConnectionString("MvcSqlLiteConnectionString")));  
    

    Once registered the DbContext can be injected into any constructor. Honestly, your GetClientsByPhoneNumberAsync should follow a standard service pattern and be injected into the MVC controller. It seems like you've skipped over the ASP.NET Core fundamentals documentation and just started coding. That's fine but you miss out on some pretty nifty features.

    The following is a standard service pattern. This is the type of pattern commonly found in repositories, domain driven design, or API development. Notice that the DbContext is injected into the constructor.

        public interface ICategoryService  
        {  
            Task<List<Category>> GetAllCategoriesAsync();  
        }  
      
        public class CategoryService : ICategoryService  
        {  
            private readonly MvcSqlLiteContext _context;  
            public CategoryService(MvcSqlLiteContext context)  
            {  
                _context = context;  
            }  
      
            public async Task<List<Category>> GetAllCategoriesAsync()  
            {  
                return await _context.Category.ToListAsync();  
            }  
      
        }  
    

    For the dependency injection to work properly, the CategoryService service must be registered. Make sure CategoryService is register after the Dbcontext registration.

    builder.Services.AddDbContext<MvcSqlLiteContext>(options =>  
           options.UseSqlite(builder.Configuration.GetConnectionString("MvcSqlLiteConnectionString")));  
      
    builder.Services.AddScoped<ICategoryService, CategoryService>();  
    

    Now, you can inject the CategoryService into an MVC controller. The DbContext is automatically injected into the CategoryService constructor.

        public class ServiceTestController : Controller  
        {  
            private readonly ICategoryService _service;  
            public ServiceTestController(ICategoryService service)  
            {  
                _service = service;  
            }  
            public async Task<IActionResult> Index()  
            {  
                var data = await _service.GetAllCategoriesAsync();  
                return Ok(data);  
            }  
        }  
    

    This pattern is covered in the asp.net fundamentals documentation. So it is not clear what you're missing exactly.

    Dependency injection in ASP.NET Core
    Service registration methods

    0 comments No comments

  4. AgaveJoe 26,166 Reputation points
    2022-07-27T18:11:38.117+00:00

    I recommend fixing your C# code so it follow standards. I can't test your code becasue I do not have all the source but your action should have the following async/await pattern.

    Asynchronous programming

     [HttpPost]  
     public async Task<TwiMLResult> InboundVoice(IncomingVoice model)  
     {  
         var response = new VoiceResponse();  
      
         GetForwardingNumber getForwardingNumber = new GetForwardingNumber();  
         string forwardingPhone = getForwardingNumber.forwardingNumber.ToString();  
           
         var tasks = new List<Task<int>>();  
         GetClientssByPhoneNumberAsync getClientsByPhoneNumberAsync = new GetClientsByPhoneNumberAsync();  
         tasks.Add(getClientsByPhoneNumberAsync.GetClientsByPhoneNumber(model.From));  
      
         LoginboundVoiceAsync loginboundVoiceAsync = new LoginboundVoiceAsync();  
         tasks.Add(loginboundVoiceAsync.LoginboundVoice(model));  
           
         response.Say("Calls may be recorded for quality assurance.");  
      
         response.Dial(forwardingPhone);  
           
         await Task.WhenAll(tasks);  
         return TwiML(response);  
     }  
    

    You tagged this thread in asp.net Core. You should use dependency injection for the DbContext rather than a using block. I would also catch the exception.

    Dependency injection in ASP.NET Core

     public class GetClientsByPhoneNumberAsync  
     {  
         private readonly myDbContext _ctx;  
         public GetClientsByPhoneNumberAsync(myDbContext ctx)   
         {  
             _ctx = ctx  
         }  
         public async Task<int> GetClientsByPhoneNumber(string phoneNumber)  
         {  
             try  
             {  
                 List<tblPtmstr1> Clients = await(_ctx.tblClients.FromSqlRaw("Exec sp_GetCleintByPhoneNumber @PhoneNumber", new SqlParameter("@PhoneNumber", phoneNumber)).ToListAsync());  
      
                 string ClientList = "";  
                 foreach (var client in Clients)  
                 {  
                     ClientList += client.ClientID + "-" + client.ClientLastName + ", " + client.ClientFirstName + "; ";  
                 }  
                 if (!(PatientList == ""))  
                 {  
                     ClientList += phoneNumber;  
                 }  
      
                 SendIncomingCallAlert sendIncomingCallAlert = new SendIncomingCallAlert(ClientList);  
      
             }  
             catch (Exception ex)  
             {  
      
             }  
             return 0;  
         }  
     }  
    

    Other than refactoring the code, I would create a test with the only the twilio bits.


  5. AgaveJoe 26,166 Reputation points
    2022-07-27T10:43:04.68+00:00

    I read the twilio documentation. Are you sure you are using Dial correctly?

    response.Dial(forwardingPhone);  
    

    https://www.twilio.com/docs/voice/twiml/dial