0

I have an object called scope that allows me to connect to a server. I want to keep that object throughout all the procedure so I need to pass it to another controller. This is the connect to server controller :

public IActionResult Proceed(Server serverModel)
        {
            if (!ModelState.IsValid) return View("Connect");
            else
            {
                try
                {
                    // --------- This is what I need to save  ------------ \\
                    ManagementScope scope = Connecting.ConnectToServer(serverModel);
                    // --------- This is what I need to save  ------------ \\
                    return RedirectToAction("Menu", "Schema");
                }
                catch (Exception e)
                {
                    ViewBag.Message = e.Message.ToString();
                    return View("Failed");
                }
            }
        }

and in the other controller I need to pass it as a parameter :

public IActionResult ExportProceed(SchemaExport ex)
        {
            if (!ModelState.IsValid) return View("Export");
            else
            {
                try
                {
                    ExportProcess.CreateDirectories(ex, scope);
                    return RedirectToAction("Menu", "Schema");
                }
                catch (Exception e)
                {
                    ViewBag.Message = e.Message.ToString();
                    return View("Failed");
                }
            }
        }
dreevo
  • 19
  • 8
  • As far as I remember, models can be sent to different controllers/actions as the third parameter for that RedirectToAction method. Like this, `return RedirectToAction("Menu", "Schema", scope);` – Tiramonium May 06 '20 at 17:31
  • Good point, you can pass them as routeValues, but be aware this makes a round trip to the user's browser. A savvy user can easily change the model that is passed to the next controller. Using TempData can sometimes be a better option. – AaronLS May 06 '20 at 17:52

2 Answers2

0

You can use TempData["YourName"] = JsonConvert.SerializeObject(Connecting.ConnectToServer(serverModel)); then you do return RedirectToAction("Menu", "Schema");.

After that you just in Controller Menu take this data from TempData.

var scope = JsonConvert.DeserializeObject<ManagementScope>((string)TempData["YourName"]);

Remember TempData lives only two request

evilGenius
  • 1,041
  • 1
  • 7
  • 16
  • I've tried that thanks for your suggestion but I get an exception : InvalidOperationException: The'Microsoft.AspNetCore.Mvc.ViewFeatures.Infrastructure.DefaultTempDataSerializer' cannot serialize an object of type 'System.Management.ManagementScope'. – dreevo May 06 '20 at 19:58
  • Now it's a compilation error cannot convert 'object' to 'string' – dreevo May 06 '20 at 20:24
  • And why you redirect to ("Menu", "Schema") if you need ExportProceed?. If you firstly go to menu and show view and only after that go to ExportProceed you TempData already be null – evilGenius May 06 '20 at 20:48
  • Ignore that redirect to action, I get compilation error when declaring that var scope with the tempdata in the second controller – dreevo May 07 '20 at 00:02
  • I had updated my answer. Forgot that TempData dynamic, json required string. var scope = JsonConvert.DeserializeObject((string)TempData["YourName"]); – evilGenius May 07 '20 at 04:00
  • converting the object management scope to a string won't allow me to use it anymore cause it's not a string. Even I tried it and I get Error converting value "System.Management.ManagementScope" to type 'System.Management.ManagementScope'. Path '' – dreevo May 07 '20 at 07:16
  • What are you taking about, you make your TempData["YourName"] which now is serialized object brings to string. Update your code in github. – evilGenius May 07 '20 at 07:37
  • Yes what I mean is the scope is used as a managementScope object not string,I've updated my code – dreevo May 07 '20 at 07:48
0

I usually don't advocate creating singletons, but as mentioned here they can be occasionally useful. Since you're not using DI this might be a good use case.

For example, what if you make your ConnectToServer class static?

public static class Connecting
{
    private static ManagementScope scope;

    public static void SetScope(Server sv)
    {
        //  WMI scope
        ConnectionOptions options = new ConnectionOptions
        {
            Username = sv.User,
            Password = sv.Pass
        };
        scope = new ManagementScope(@"\\" + sv.Name + @"\root\cimv2", options);
        scope.Connect();
    }

    public static ManagementScope GetScope { get { return scope; } }
}

Then in your Proceed action:

// ---------- This is the function returning the scope ---------- \\
Connecting.SetScope(serverModel);
// ---------- This is the function returning the scope ---------- \\

And in your ExportProceed action:

// ---------- This is where i need to pass the scope ---------- \\
var scope = Connecting.GetScope;
ExportProcess.CreateDirectories(ex, scope);
// ---------- This is where i need to pass the scope ---------- \\
crgolden
  • 4,332
  • 1
  • 22
  • 40
  • If I declare scope as a readonly then I won't be able to asign it to a value (new management scope) cause it's a readonly – dreevo May 07 '20 at 07:55
  • Also in the ExportProceed It says Non-invocable member 'Get scope' can't be called as a method – dreevo May 07 '20 at 07:58
  • @dreevo updated from method call to property access (`var scope = Connecting.GetScope`) – crgolden May 07 '20 at 07:59