Передавать сложный объект между методами действия ASP. Net MVC Core - PullRequest
0 голосов
/ 29 мая 2020

Я изучил большинство подобных вопросов, но не нашел ответа! Позвольте мне заявить, что я могу определить простой TempData, например строку int, и успешно получить его в другом методе действия, но

У меня есть 3 параметра / переменная в ActionMethod1, которая называется «ExternalLoginCallBack», и мне нужно спросить «UserName» от пользователя на стороне клиента, а затем сохраните все 4 параметра в ActionMethod2, который называется «CreateExternalUser». Это то, что у меня есть. AskUserNameView_NoActionMethod.cs html, как показано ниже:

@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.cs html он показывает просто белая страница без ошибок, без исключения и ничего: enter image description here

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.cs html успешно отображается, и я могу передать 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 параметрами (электронная почта, ReturnUrl, ExternalLoginInfo) для строго типизированного AskUserNameView_NoActionMethod.cs html, но снова имя пользователя, введенное на стороне клиента, электронная почта и returnUrl переданы в ActionMethod2, но externalLoginInfo был нулевым.

Резюме: нужен пример для передачи сложных данных / объекта из actionmethod1 в actionmethod2 без перенаправления на actionmethod2 !!

1 Ответ

0 голосов
/ 30 мая 2020

У вас есть два метода для достижения этого.

Поскольку TempData не может хранить здесь сложный объект, вы можете Serialize объект в строку json и сохранить его в TempData, тогда вы можете получить json строка в действии CreateExternalUser и 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(); 
        }

Другой метод - создать a custom method с именем TempDataExtensions для передачи объекта из действия в другое.

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");
...