【问题标题】:Splitting a string throws InvalidOperationException when hosting on IIS在 IIS 上托管时拆分字符串会引发 InvalidOperationException
【发布时间】:2018-08-17 14:55:47
【问题描述】:

我写了以下代码:

private string makeMailContents(Klant klant, Mail mail)
{
    var builder = new BodyBuilder();
    var path = Path.Combine("wwwroot/trackers/track_open.png");
    var img = builder.LinkedResources.Add(path);
    byte[] data = Convert.FromBase64String(mail.Content);
    string decoded = Encoding.UTF8.GetString(data);
    string code;
    string final = "";
    Regex regex = new Regex(@"\[([^]]*)\]");

    img.ContentId = MimeUtils.GenerateMessageId();

    var splitContent = decoded.Split(' ');

    foreach(string word in splitContent) // this is line 265
    { 
            if (word.Contains('[') && word.Contains(']'))
            {
                try
                {
                    code = Regex.Match(word, @"\[([^]]*)\]").Groups[1].Value.ToLower();
                    switch (code)
                    {
                        case "voornaam":
                            final += regex.Replace(word, klant.vnaam) + ' ';
                            break;
                        case "achternaam":
                            final += regex.Replace(word, klant.anaam) + ' ';
                            break;
                        case "naam":
                            final += regex.Replace(word, klant.vnaam + ' ' + klant.anaam + ' ');
                            break;
                        case "onderwerp":
                            final += regex.Replace(word, mail.Onderwerp + ' ');
                            break;
                        case "datum":
                            final += regex.Replace(word, DateTime.Now.ToString("dd-MM-yyyy") + ' ');
                            break;
                    }
                }
                catch (Exception ex)
                {
                    final += ex;
                }
            }
            else
            {
                final += word + ' ';
            }
    }
}

每当我在本地机器和测试服务器上运行此代码时,它都会按照应有的方式执行代码,没有任何异常。

但每当我在当前的实时服务器上托管它时,它都会引发以下异常:

InvalidOperationException:序列不包含任何元素

这个异常一直指向splitContent,它告诉我它不包含元素。是的,mail.Content 填充了一个有效的base64 字符串,我检查了提琴手和邮递员。

有人知道这里发生了什么吗?我也不确定是 IIS 设置还是我的代码。我通常有一个管理 IIS 的同事,但他现在正在休假。有人可以帮我解决这个问题吗?

这是邮件在调用时收到的数据:

 {      
    "Onderwerp":"Dit is een test campagne",
    "afzender":1,
    "campagne":1,
    "Content":"PHA+RGl0IGlzIGVlbiB0ZXN0IG1hYXQ8L3A+Cg==",
    "docs":"['kamer2.jpg']",
    "template":null,
    "verzenddat":"8/17/18, 3:55 PM"
}

完全例外:

System.InvalidOperationException: Sequence contains no elements
   at System.Linq.Enumerable.Last[TSource](IEnumerable`1 source)
   at lambda_method(Closure , QueryContext )
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.<>c__DisplayClass17_1`1.<CompileQueryCore>b__0(QueryContext qc)
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.Execute[TResult](Expression query)
   at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryProvider.Execute[TResult](Expression expression)
   at System.Linq.Queryable.Last[TSource](IQueryable`1 source)
   at MailerAPI.Mailer.Sender.makeMailContents(Klant klant, Mail mail) in C:\Users\Hofkey\Source\Repos\MailerAPI\MailerAPI\Mailer\Sender.cs:line 265
   at System.Dynamic.UpdateDelegates.UpdateAndExecute3[T0,T1,T2,TRet](CallSite site, T0 arg0, T1 arg1, T2 arg2)
   at MailerAPI.Mailer.Sender.<sendMessage>d__7.MoveNext() in C:\Users\Hofkey\Source\Repos\MailerAPI\MailerAPI\Mailer\Sender.cs:line 161
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at MailerAPI.Controllers.MailController.<Post>d__13.MoveNext() in C:\Users\Hofkey\Source\Repos\MailerAPI\MailerAPI\Controllers\MailController.cs:line 96
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.<InvokeActionMethodAsync>d__12.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.<InvokeNextActionFilterAsync>d__10.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Rethrow(ActionExecutedContext context)
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.<InvokeInnerFilterAsync>d__14.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.<InvokeNextResourceFilter>d__22.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Rethrow(ResourceExecutedContext context)
   at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.<InvokeFilterPipelineAsync>d__17.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.<InvokeAsync>d__15.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNetCore.Builder.RouterMiddleware.<Invoke>d__4.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNetCore.Cors.Infrastructure.CorsMiddleware.<Invoke>d__7.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.<Invoke>d__7.MoveNext()

当我用纯字符串替换模型属性时也会引发异常。

更新 每当我在我的值控制器中运行此代码以测试 decoded.split(' ') 时,它确实有效。当我返回 decoded.split(' ') 时,我实际上得到了一个字符串数组。

所以现在我知道问题只发生在方法内部,该方法位于Sender类中并在MailerController中被调用,并且也只发生在当前服务器中。

【问题讨论】:

  • @ViggoLundén:不是这样。如果你在string test = "StringWithNoSpaces"; 之后运行var res = test.Split(' ');,你最终会得到一个包含原始字符串的单元素数组。它不会抛出。
  • 堆栈跟踪通过例如显示 Entity Framework 相关提示。命名空间Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler。我假设klant 变量是一个Entity Framework 对象,并且它在// something 块中以一种导致EF 抛出的方式被寻址。请显示// something 块。还要在foreach 循环中添加一个try/catch,其中包含klant 数据的一些日志记录,因为它可能与数据相关。
  • 同意,堆栈跟踪直接从makeMailContentsLinq.Queryable.Last,所以看起来问题在于// something 在空序列上调用Last()。发布的代码中没有似乎能够做到这一点。
  • 请阅读How to Ask 并创建一个minimal reproducible example。这不是所有的代码,并且您显示的代码不会重现您描述的问题。
  • 能分享一下包含MailController.cs:line 96的方法以及Sender.cs中涉及的所有方法吗?我希望看到正在执行的任何 EF Linq 语句。

标签: c# asp.net iis asp.net-core


【解决方案1】:

您似乎正在通过位于C:\Users\Hofkey\Source\Repos\MailerAPI\MailerAPI\Mailer\Sender.cs:line 265 的代码或通过位于C:\Users\Hofkey\Source\Repos\MailerAPI\MailerAPI\Mailer\Sender.cs:line 265 的代码拨打.Last()

Linq 扩展方法.Last() 要求至少有一项可以抓取。要解决此要求,您有多种选择:

  • 使用.LastOrDefault() 并配合适当的null 处理,或
  • 在使用.Last()之前,先检查if (... .Any())是否可以拨打.Last()


如需进一步参考,请参阅LINQ Element Operations

【讨论】:

    猜你喜欢
    • 2012-01-02
    • 1970-01-01
    • 1970-01-01
    • 2020-08-17
    • 1970-01-01
    • 1970-01-01
    • 2015-08-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多