简体   繁体   中英

How do I pass data from a database from one controller to another controller that has its own database in ASP.NET Core?

I have two controllers:

AaController have a view named Index and a database context that we can call for dbContextAa

RrController also has its own database, which we can call for dbContextRr and an action method GetData ()

What I wonder is; how do I do if I want to take the data from the method GetData () and display it in the index view.

Previously, I tested with Temp Data and Sessions without any result. I had no value at all in the view from RrDatabase. If I understand it right, I have to use Dependency Injections.

So here I have created dependency injection (not sure if it is correct)

AaController:

public class AaController : Controller
{
    private RrController rc;

    public AaController(RrController rr, AaContext aaContext)
    {
        rc = rr;
        _aaContext = aaContext;
    }

public IActionResult Index()
    {
        var dataFromRr= rs.GetData();

        ViewBag.rrData = dataFromRr;

        return View();
    }

RrController:

public class RrController : Controller
{
    private readonly RrContext _rrContext;

    public RrController(RrContext rrContext)
    {
        _rrContext = rrContext;
    }

public IActionResult GetData()
    {
        var data = _rrContext.RrData.Count(x => x.Pid == x.Pid);


        return RedirectToAction("Index", "Aa", data );
    }

Instead of the value of the view I get Microsoft.AspNetCore.Mvc.ViewResult.

How do I solve this?

Because GetData method returns an IActionResult type response(specifically MVC action result, RedirectResult ).

Ideally what you should be doing is, extract the code which gives you the relevant data to a method in a separate class, which you can use in multiple places as needed (ControllerA and ControllerR).

Let's create an interface and a class to implement it.

public interface IRService
{
   int GetRDataCount(int pId);
}

public class RService : IRService
{
   private RrContext _rrContext;     
   public RService (RrContext rrContext)
   {
      this._rrContext=rrContext;
   }  
   public int GetRDataCount(int pId)
   {
     return _rrContext.RrData.Count(x => x.Pid == pId);
   }
} 

You can inject IRService implementation to your controllers and call the GetRDataCount method to get the int value.

public class AaController : Controller
{
    private IRService rService;

    public AaController(IRService rService)
    {
        this.rService=rService;
    }

    public IActionResult Index()
    {
        int countVal = this.rService.GetRDataCount(234); // pass actual PId

        ViewBag.rrData = countVal;

        return View();
    }    
}

Make sure to add the IRservice to RService dependency mapping in your Startup class.

Now wherever you want to get the RData count for a specific pId, you can inject an IRservice implementation and use it (Do it in your RController as well)

There are a few different approaches depending on the structure of your projects and how (and if) they can communicate with one another.

What I wonder is; how do I do if I want to take the data from the method GetData () and display it in the index view.

Your GetData() method is actually attempting to return a View on it's own, however it looks like what you want to do is actually just return the data (ie the count) and pass that to your other action:

public int GetData()
{
    var data = _rrContext.RrData.Count(x => x.Pid == x.Pid);
    // This will pass a parameter that contains your count
    return RedirectToAction("Index", "Aa", new { count = data });
}

You need to actually pass your data to the View as a "model". This can easy be done by simply decorating your View with the type of data that you are going to be passing in:

public IActionResult Index(int count)
{
    // The count parameter will have the current result of your previous call in it
    return View(count);
}

Then you would just need to tell your actual View how you wanted to present the data (ie what type it was) via the @model directive at the top of the view:

@model int

There were @Model records found.

Consider A Service

A better implementation would be to consider using a service that decouples your logic from any one specific controller. This would allow you to simply instantiate the service and call it from wherever it was needed as Shyju's answer indicates.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM