Asp.net core TempData 在添加列表并重定向到另一个视图时给出 500 错误 [英] Asp.net core TempData give 500 error when adding list and redirect to another view

查看:12
本文介绍了Asp.net core TempData 在添加列表并重定向到另一个视图时给出 500 错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试建立警报列表并将它们添加到 TempData.但如果我不做重定向,它会起作用.当我重定向它给我 500 错误.我也设置了断点,但是在重定向时它没有命中,否则它正确命中.

I am try to build alerts list and added them to TempData. But it work if I did not do redirect. When I do redirect it give me 500 error. I set break point in view as well but it did not hit when did redirect other wise it hit correctly.

动作方法

public IActionResult Create(CategoryCreateVM input)
{
    if (ModelState.IsValid)
    {
        var category = mapper.Map<Categories>(input);
        categoryBL.Add(category);

        List<Alert> alert = new List<Alert>();
        alert.Add(new Alert("alert-success", "success message"));
        alert.Add(new Alert("alert-danger", "danger message"));

        TempData["Alert"] = alert;

        return RedirectToAction("Index");
    }
    return View(input);
}

我如何在视图中访问.

@{ 
    var alerts = TempData["Alert"] as List<Alert>;
}
@if (alerts != null && alerts.Count > 0)
{
    <div class="">
        @foreach (var alert in alerts)
        {
            <div class="alert @alert.AlertClass alert-dismissible">
                <button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button>
                @alert.Message
            </div>

        }
    </div>

}

堆栈跟踪.

    Exception thrown: 'System.InvalidOperationException' in Microsoft.AspNetCore.Mvc.ViewFeatures.dll
Exception thrown: 'System.InvalidOperationException' in mscorlib.dll
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker: Information: Executed action MvcSandbox.Controllers.HomeController.Index (MvcSandbox) in 46.4619ms
Exception thrown: 'System.InvalidOperationException' in mscorlib.dll
Exception thrown: 'System.InvalidOperationException' in mscorlib.dll
Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware: Error: An unhandled exception has occurred while executing the request

System.InvalidOperationException: The 'Microsoft.AspNetCore.Mvc.ViewFeatures.Internal.TempDataSerializer' cannot serialize an object of type 'MvcSandbox.Controllers.Alert'.
   at Microsoft.AspNetCore.Mvc.ViewFeatures.Internal.TempDataSerializer.EnsureObjectCanBeSerialized(Object item) in D:	empMvc-devsrcMicrosoft.AspNetCore.Mvc.ViewFeaturesInternalTempDataSerializer.cs:line 207
   at Microsoft.AspNetCore.Mvc.ViewFeatures.Internal.TempDataSerializer.Serialize(IDictionary`2 values) in D:	empMvc-devsrcMicrosoft.AspNetCore.Mvc.ViewFeaturesInternalTempDataSerializer.cs:line 142
   at Microsoft.AspNetCore.Mvc.ViewFeatures.SessionStateTempDataProvider.SaveTempData(HttpContext context, IDictionary`2 values) in D:	empMvc-devsrcMicrosoft.AspNetCore.Mvc.ViewFeaturesViewFeaturesSessionStateTempDataProvider.cs:line 62
   at Microsoft.AspNetCore.Mvc.ViewFeatures.TempDataDictionary.Save() in D:	empMvc-devsrcMicrosoft.AspNetCore.Mvc.ViewFeaturesViewFeaturesTempDataDictionary.cs:line 166
   at Microsoft.AspNetCore.Mvc.ViewFeatures.Internal.SaveTempDataFilter.SaveTempData(IActionResult result, ITempDataDictionaryFactory factory, HttpContext httpContext) in D:	empMvc-devsrcMicrosoft.AspNetCore.Mvc.ViewFeaturesInternalSaveTempDataFilter.cs:line 91
   at Microsoft.AspNetCore.Mvc.ViewFeatures.Internal.SaveTempDataFilter.OnResultExecuted(ResultExecutedContext context) in D:	empMvc-devsrcMicrosoft.AspNetCore.Mvc.ViewFeaturesInternalSaveTempDataFilter.cs:line 80
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted) in D:	empMvc-devsrcMicrosoft.AspNetCore.Mvc.CoreInternalControllerActionInvoker.cs:line 1023
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.<InvokeNextResourceFilter>d__22.MoveNext() in D:	empMvc-devsrcMicrosoft.AspNetCore.Mvc.CoreInternalControllerActionInvoker.cs:line 1105
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Rethrow(ResourceExecutedContext context) in D:	empMvc-devsrcMicrosoft.AspNetCore.Mvc.CoreInternalControllerActionInvoker.cs:line 1377
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted) in D:	empMvc-devsrcMicrosoft.AspNetCore.Mvc.CoreInternalControllerActionInvoker.cs:line 493
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.<InvokeAsync>d__20.MoveNext() in D:	empMvc-devsrcMicrosoft.AspNetCore.Mvc.CoreInternalControllerActionInvoker.cs:line 164
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   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.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
   at Microsoft.AspNetCore.Session.SessionMiddleware.<Invoke>d__9.MoveNext() in D:	empSession-devSession-devsrcMicrosoft.AspNetCore.SessionSessionMiddleware.cs:line 106
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at Microsoft.AspNetCore.Session.SessionMiddleware.<Invoke>d__9.MoveNext() in D:	empSession-devSession-devsrcMicrosoft.AspNetCore.SessionSessionMiddleware.cs:line 123
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.<Invoke>d__7.MoveNext()
Exception thrown: 'System.InvalidOperationException' in Microsoft.AspNetCore.Http.dll
Microsoft.AspNetCore.Server.Kestrel: Error: Connection id "0HL1I8OFS17SU": An unhandled exception was thrown by the application.

System.InvalidOperationException: Session has not been configured for this application or request.
   at Microsoft.AspNetCore.Http.DefaultHttpContext.get_Session()
   at Microsoft.AspNetCore.Mvc.ViewFeatures.SessionStateTempDataProvider.SaveTempData(HttpContext context, IDictionary`2 values) in D:	empMvc-devsrcMicrosoft.AspNetCore.Mvc.ViewFeaturesViewFeaturesSessionStateTempDataProvider.cs:line 57
   at Microsoft.AspNetCore.Mvc.ViewFeatures.TempDataDictionary.Save() in D:	empMvc-devsrcMicrosoft.AspNetCore.Mvc.ViewFeaturesViewFeaturesTempDataDictionary.cs:line 166
   at Microsoft.AspNetCore.Mvc.ViewFeatures.Internal.SaveTempDataFilter.SaveTempData(IActionResult result, ITempDataDictionaryFactory factory, HttpContext httpContext) in D:	empMvc-devsrcMicrosoft.AspNetCore.Mvc.ViewFeaturesInternalSaveTempDataFilter.cs:line 91
   at Microsoft.AspNetCore.Mvc.ViewFeatures.Internal.SaveTempDataFilter.<>c.<OnResultExecuting>b__5_0(Object state) in D:	empMvc-devsrcMicrosoft.AspNetCore.Mvc.ViewFeaturesInternalSaveTempDataFilter.cs:line 57
   at Microsoft.AspNetCore.Server.Kestrel.Internal.Http.Frame.<FireOnStarting>d__178.MoveNext()
Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware: Error: An exception was thrown attempting to display the error page.

System.ObjectDisposedException: The response has been aborted due to an unhandled application exception. ---> System.InvalidOperationException: Session has not been configured for this application or request.
   at Microsoft.AspNetCore.Http.DefaultHttpContext.get_Session()
   at Microsoft.AspNetCore.Mvc.ViewFeatures.SessionStateTempDataProvider.SaveTempData(HttpContext context, IDictionary`2 values) in D:	empMvc-devsrcMicrosoft.AspNetCore.Mvc.ViewFeaturesViewFeaturesSessionStateTempDataProvider.cs:line 57
   at Microsoft.AspNetCore.Mvc.ViewFeatures.TempDataDictionary.Save() in D:	empMvc-devsrcMicrosoft.AspNetCore.Mvc.ViewFeaturesViewFeaturesTempDataDictionary.cs:line 166
   at Microsoft.AspNetCore.Mvc.ViewFeatures.Internal.SaveTempDataFilter.SaveTempData(IActionResult result, ITempDataDictionaryFactory factory, HttpContext httpContext) in D:	empMvc-devsrcMicrosoft.AspNetCore.Mvc.ViewFeaturesInternalSaveTempDataFilter.cs:line 91
   at Microsoft.AspNetCore.Mvc.ViewFeatures.Internal.SaveTempDataFilter.<>c.<OnResultExecuting>b__5_0(Object state) in D:	empMvc-devsrcMicrosoft.AspNetCore.Mvc.ViewFeaturesInternalSaveTempDataFilter.cs:line 57
   at Microsoft.AspNetCore.Server.Kestrel.Internal.Http.Frame.<FireOnStarting>d__178.MoveNext()
   --- End of inner exception stack trace ---
   at Microsoft.AspNetCore.Server.Kestrel.Internal.Http.Frame.ThrowResponseAbortedException()
   at Microsoft.AspNetCore.Server.Kestrel.Internal.Http.Frame.<ProduceStartAndFireOnStartingAwaited>d__194.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNetCore.Server.Kestrel.Internal.Http.Frame.Write(ArraySegment`1 data)
   at Microsoft.AspNetCore.Server.Kestrel.Internal.Http.FrameResponseStream.Write(Byte[] buffer, Int32 offset, Int32 count)
   at System.IO.StreamWriter.Flush(Boolean flushStream, Boolean flushEncoder)
   at System.IO.StreamWriter.Write(String value)
   at Microsoft.Extensions.RazorViews.BaseView.Write(String value)
   at Microsoft.AspNetCore.Diagnostics.RazorViews.ErrorPage.<ExecuteAsync>d__6.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.Extensions.RazorViews.BaseView.<ExecuteAsync>d__29.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.<Invoke>d__7.MoveNext()
Microsoft.AspNetCore.Server.Kestrel: Error: Connection id "0HL1I8OFS17SU": An unhandled exception was thrown by the application.

推荐答案

我在深入研究源代码后终于弄清楚了问题所在.Asp.Net Core MVC 目前不支持 TempData 的复杂数据类型.它目前只支持 string.它在序列化数据时通过这个异常,如果我们传递其他的那么 string.

Finally I figured it out what's the issue after digging into the source code. Asp.Net Core MVC not supported complex data type for TempData currently. It only support string for now. It through this exception while serialize data, if we pass other then string.

Microsoft.AspNetCore.Mvc.ViewFeatures.Internal.TempDataSerializer"无法序列化MvcSandbox.Controllers.Alert"类型的对象.

The 'Microsoft.AspNetCore.Mvc.ViewFeatures.Internal.TempDataSerializer' cannot serialize an object of type 'MvcSandbox.Controllers.Alert'.

我将我的列表序列化为 json,然后保存在 TempData 中.

I serialize my list to json and then save in TempData.

我是这样做的.我创建扩展方法来从 TempData 添加和检索数据.

Here is how I did this. I create extension method to add and retrieve data from TempData.

const string Alerts = "Alerts";
public static List<Alert> GetAlert(this ITempDataDictionary tempData)
{
    CreateAlertTempData(tempData);
    return DeserializeAlerts(tempData[Alerts] as string);
}

public static void CreateAlertTempData(this ITempDataDictionary tempData)
{
    if (!tempData.ContainsKey(Alerts))
    {
        tempData[Alerts] = "";
    }
}
public static void AddAlert(this ITempDataDictionary tempData, Alert alert)
{
    if(alert == null)
    {
        throw new ArgumentNullException(nameof(alert));
    }
    var deserializeAlertList = tempData.GetAlert();
    deserializeAlertList.Add(alert);
    tempData[Alerts] = SerializeAlerts(deserializeAlertList);
}
public static string SerializeAlerts(List<Alert> tempData)
{
    return JsonConvert.SerializeObject(tempData);
}
public static List<Alert> DeserializeAlerts(string tempData)
{
    if(tempData.Length == 0)
    {
        return new List<Alert>();
    }
    return JsonConvert.DeserializeObject<List<Alert>>(tempData);
}

添加警报 TempData

 tempData.AddAlert(new Alert(AlertClass, Message));

最终得到'TempDatainView'并显示出来.

Finally get 'TempDatainView' and display.

@if (TempData.GetAlert().Count > 0)
{
    <div class="alert-container">
        @foreach (var alert in TempData.GetAlert())
        {
            <div class="alert @alert.AlertClass alert-dismissible">
                <button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button>
                @alert.Message
            </div>
        }
    </div>
}

这篇关于Asp.net core TempData 在添加列表并重定向到另一个视图时给出 500 错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆