【问题标题】:Pass complex object between action methods ASP.Net MVC Core在操作方法 ASP.Net MVC Core 之间传递复杂对象
【发布时间】:2020-05-29 06:48:51
【问题描述】:

我研究了大多数类似的问题,但找不到答案! 让我声明,我可以定义一个简单的 TempData 像一个字符串,int 并成功地在另一个动作方法中获取它,但是

我在 ActionMethod1 中有 3 个参数/变量,名为“ExternalLoginCallBack”,需要在客户端向用户询问“UserName”,然后将总共 4 个参数保存在名为“CreateExternalUser”的 ActionMethod2 中。 这就是我所拥有的。 AskUserNameView_NoActionMethod.cshtml 如下:

@model ExternalUserViewModel

<form asp-action="CreateExternalUser" asp-controller="Account" method="post">        
        <label asp-for="UserName">Input your UserName Here: </label>
        <input asp-for="UserName" >                      
        <input  type="submit" value="ُSubmit"/>
</form>

(使用 TempData)Attemp-No.1:

public async Task<IActionResult> ActionMethod1

//some codes here

var externalLoginInfo = await _signInManager.GetExternalLoginInfoAsync();
TempData["externalLoginInfo"] = externalLoginInfo;
TempData["email"] = email;
TempData["returnUrl"] = returnUrl;

return View("AskUserNameView_NoActionMethod");

但不是显示 AskUserNameView_NoActionMethod.cshtml 它只显示一个没有错误的白页,没有异常,什么都没有:

Attemp-No2:我删除了“ExternalLoginInfo”类型,只剩下两个简单的字符串作为对象传递给 ActionMethod2:

public async Task<IActionResult> ActionMethod1

//some codes here


var externalUserViewModel= new ExternalUserViewModel()
{   
Email = email,
ReturnUrl = returnUrl,
};   

TempData["externalUserViewModel"] = externalUserViewModel;

return View("AskUserNameView_NoActionMethod");

但上面的白页又出现了。当我删除复杂的 TempData 时,我的 AskUserNameView_NoActionMethod.cshtml 渲染成功,我可以将客户端输入的 UserName 传递给 ActionMethod2。但是没有创建新外部用户所需的 3 个其他参数!

我的 ExternalUserViewModel 如下:

 public class ExternalUserViewModel
{
    public ExternalLoginInfo ExternalLoginInfo { get; set; }
    public string Email { get; set; }

    public string UserName { get; set; }
    public string ReturnUrl { get; set; }
}

并且已经将这些代码添加到 startup.cs:

services.AddControllersWithViews();
services.AddSingleton<ITempDataProvider, CookieTempDataProvider>();

app.UseSession();

如果 TempData 不适用,我尝试将带有 3 个参数(Email、ReturnUrl、ExternalLoginInfo)的模型传递给强类型 AskUserNameView_NoActionMethod.cshtml,但客户端再次输入用户名、Email 和返回的Url 传递给 ActionMethod2 但 externalLoginInfo 为空.

总结:需要一个示例将复杂的数据/对象从 actionmethod1 传递到 actionmethod2 ,而不重定向到 actionmethod2 !

【问题讨论】:

    标签: asp.net-core-mvc


    【解决方案1】:

    你有两种方法来实现它。

    由于TempData不能在这里存储复杂对象,你可以Serialize对象到json字符串并存储在TempData中,然后你可以在CreateExternalUser动作中获取json字符串和Deserialize这个json字符串到对应的对象为关注:

        public async Task<IActionResult> ActionMethod1()
        {
    
            //some codes here 
            var externalLoginInfo = await _signInManager.GetExternalLoginInfoAsync();
            TempData["externalLoginInfo"] = JsonConvert.SerializeObject(externalLoginInfo);
            TempData["email"] = email;
            TempData["returnUrl"] = returnUrl;
    
            return View("AskUserNameView_NoActionMethod");
    
        }
    

    接收:

    public async Task<IActionResult> CreateExternalUser(UserName  userName)
            {
                //some codes here 
                var externalLoginInfo = JsonConvert.DeserializeObject<ExternalLoginInfo>(TempData["externalLoginInfo"].ToString());
    
               var email = TempData["email"] as string;
                var returnUrl = TempData["returnUrl"] as string;
    
                return View(); 
            }
    

    另一种方法是创建名为TempDataExtensionsa custom method 将对象从一个动作传递到另一个动作。

    public static class TempDataExtensions
    {
        public static void Put<T>(this ITempDataDictionary tempData, string key, T value) where T : class
        {
            tempData[key] = JsonConvert.SerializeObject(value);
        }
    
        public static T Get<T>(this ITempDataDictionary tempData, string key) where T : class
        {
            object o;
            tempData.TryGetValue(key, out o);
            return o == null ? null : JsonConvert.DeserializeObject<T>((string)o);
        }
    }
    

    存储对象:

    var externalLoginInfo = await _signInManager.GetExternalLoginInfoAsync();
    TempData.Put("externalLoginInfo", externalLoginInfo);
    

    获取对象:

    var externalLoginInfo = TempData.Get<ExternalLoginInfo>("externalLoginInfo");
    

    【讨论】:

    • @ehsan_kabiri_33 ,如果我的回答能帮助你解决问题,请标记为答案,如果有问题,请告诉我。
    • 使用:TempData[key] = JsonConvert.SerializeObject(value);导致错误:此实例包含无法在此平台上序列化和反序列化并使用的状态: TempData["model"] = JsonSerializer.Serialize(model, new JsonSerializerOptions { MaxDepth = 64 });它导致错误:检测到不支持的可能对象循环-我尝试在 startup.cs 中进行一些更改,但没有成功。
    • 你的代码是真的。问题在于“externalLoginInfo”,它会创建一个循环/循环并导致错误。我现在可以通过您的代码发送简单对象,但仍然无法将上面的“externalLoginInfo”分配给 TempData。
    猜你喜欢
    • 2023-03-27
    • 1970-01-01
    • 2021-02-22
    • 1970-01-01
    • 1970-01-01
    • 2018-05-19
    • 1970-01-01
    • 2013-02-26
    • 1970-01-01
    相关资源
    最近更新 更多