locked
Pass dataset from one controller to another controllers async Task fucntion RRS feed

  • Question

  • User1897897189 posted

    Dears,

    Please help me to figure out the exact issue in my code.


    I have a view(s.cshtml) which accepts input parameters from the user. The input parameters is passed to a controller (sController.cs) and i have the following code;

    sController.cs

    public ActionResult Index()
    {
    return View();
    }
    [HttpPost]
    public async Task<ActionResult> IndexAsync(string Input)
    {

    var c = new MController();
    var MData = Task.Run(() => c.M(Input));
    await Task.WhenAll(MData);
    return View();
    }

    From the view,s.cshtml,I am calling a partial view _MServices.cshtml (@Html.Partial("~/Views/M/_MServices.cshtml",null) )
    which is associated to a controller Mcontroller.cs

    Following is my _MServices.cshtml
    @using System.Data
    @model DataSet
    @{
    Layout = null;
    }

    @if (Model != null)
    {
    if (Model.Tables.Contains("dt"))

    {

    foreach (DataRow dr in Model.Tables[0].Rows)

    {
    }
    }
    }


    Following is Mcontroller.cs
    public class MController : Controller

    {

    public static DataSet s_details(string No)
    {
    DataSet ds = new DataSet();
    DataTable dt = new DataTable("dt");
    ds.Tables.Add(dt);

    return ds;
    }

    public ActionResult M(string No)

    {

    DataSet ds = new DataSet();
    ds = s_details(No);
    return View(ds);
    }
    }

    The issue is, the view _MServices.cshtml is not getting the dataset from the controller Mcontroller.

    When i debug the code, i found that after the "return View(ds)" in Mcontroller,
    the control is directly going to sController's IndexAsync(string Input) function and the "return View()" statement there
    returns empty value to _MServices.cshtml


    Where am i going wrong? Can anyone here please help me?


    Thanks
    Nick

    Friday, July 31, 2020 5:21 AM

All replies

  • User1686398519 posted

    Hi nicklibee,

    (@Html.Partial("~/Views/M/_MServices.cshtml",null)

    When you render the partial view, you do not pass data to the partial view, so the data that your partial view gets is empty.

    I modified it based on the code you provided, please refer to it.

    • You need to use ViewData["test"] to store the data returned by the controller named M, and pass the data to the partial view when rendering.

    IndexAsync

            [HttpPost]
            public async Task<ActionResult> IndexAsync(string Input)
            {
    
                var c = new MController();
                var MData = Task.Run(() => c.M(Input));
                await Task.WhenAll(MData);
                var result=MData.Result as ViewResult; 
                ViewData["test"] = result.Model;
                return View("Index");
            }

    s_details

            public static DataSet s_details(string No)
            {
                DataSet ds = new DataSet();
                DataTable dt = new DataTable("dt");
                dt.Columns.Add(new DataColumn("name", typeof(string)));
                DataRow dr = dt.NewRow();
                dr["name"] = No;
                dt.Rows.Add(dr);
                ds.Tables.Add(dt);
                return ds;
            }

    Index

    @using (Html.BeginForm("IndexAsync", "Test", FormMethod.Post))
    {
        <input name="Input" />
        <button type="submit">submit</button>
    }
    @Html.Partial("~/Views/M/_MServices.cshtml", ViewData["test"])

    _MServices.cshtml

    @using System.Data
    @model DataSet
    @{
        Layout = null;
    }
    @if (Model != null)
    {
        if (Model.Tables.Contains("dt"))
        {
        <table class="table">
            <tr><td>name</td></tr>
            @foreach (DataRow dr in Model.Tables[0].Rows)
            {
                <tr><td>@dr["name"]</td></tr>
            }
        </table>
        }
    }

    Here is the result.

    Best Regards,

    YihuiSun

    Monday, August 3, 2020 3:13 AM
  • User1897897189 posted

    Wow wow wow....................You are the best............It is working.............So happy and thrilled....

    I could see it but the final output cannot be seen on the Page....

    Your logic is correct, but i think it's reloading the entire layout page.. I could see the dataset & the values got rendered on the partial view...

    Any idea where I am going wrong... Please.

    After rendering the partial view, control goes back to the layout page.. How can I stop that??

    Removed Httppost

     [HttpPost]
            public async Task<ActionResult> IndexAsync(string Input)
            {}

    If I keep the httppost page is not loading...I think that is the problem

    Monday, August 3, 2020 7:04 PM
  • User1686398519 posted

    Hi nicklibee,

    After rendering the partial view, control goes back to the layout page.. How can I stop that??

    I suggest you use ajax which can meet your needs well.

    More details, you could refer to below code:

    Controller

            [HttpPost]
            public async Task<ActionResult> IndexAsync(string Input)
            {
    
                var c = new MController();
                var MData = Task.Run(() => c.M(Input));
                await Task.WhenAll(MData);
                var result = MData.Result as ViewResult;
                return PartialView("~/Views/M/_MServices.cshtml", result.Model);
            }

    Index

    <input id="inputtest" name="Input" />
    <button id="test" type="submit">submit</button>
    <div id="showpartialview">
    </div>
    @section scripts{
        <script>
            $('#test').click(function () {
                $.ajax({
                    url: '@Url.Action("IndexAsync","Test")',
                    type: 'POST',
                    data: {
                        Input: $("#inputtest").val()
                    },
                    success: function (data) {
                        $("#showpartialview").html(data);
                    }
                });
            });
        </script>
    }

    Here is the result.

    Best Regards,

    YihuiSun

    Tuesday, August 4, 2020 7:51 AM
  • User1897897189 posted

    Thanks...

    It shows the following error message

    "The following sections ave been defined but have not been rendered for the layout page"

    On my layout page i ahve @rendersection("meta",false);

    @rendersection("scripts",false);

    Its working added @rendersection("scripts",false) but the issue data is displayed on a seperate page not within the main view it self

    what could be the reason?

    nick

    Tuesday, August 4, 2020 8:14 AM
  • User1686398519 posted

    Hi nicklibee,

    @RenderSection is used to inject content in the defined section. It allows you to specify areas in the Layout.

    Because my _Layout.cshtml defines "@RenderSection("scripts", required: false)" and the Index page uses _Layout.cshtml, I put the js code in "@section scripts{ }".

    According to the code you gave, you defined "@RenderSection("meta",false)" in _Layout.cshtml, so you should write like this.

    @section meta{
      @*js code*@
    }

    Here is my _Layout.cshtml.

    @Scripts.Render("~/bundles/jquery")
    @Scripts.Render("~/bundles/bootstrap")
    @RenderSection("scripts", required: false)
    @RenderSection("meta",false)

    Best Regards,

    YihuiSun

    Tuesday, August 4, 2020 8:49 AM
  • User1897897189 posted

    Still the same. Applied your logic , still the partial view is displayed on a separate page...

    Tuesday, August 4, 2020 9:15 AM
  • User1686398519 posted

    Hi nicklibee,

    but the issue data is displayed on a seperate page not within the main view it self

    Do you mean that the partial view is not added to the Index view?You can look at the example I provided. I added "<div id="showpartialview"></div>" to the Index view. When the ajax request is successful, the partial view is placed in this div.

    There is also a small suggestion. If you need to describe your problem again, you can directly follow up, and we can help you better.

    Best Regards,

    YihuiSun

    Tuesday, August 4, 2020 9:20 AM
  • User1897897189 posted

    Do you mean that the partial view is not added to the Index view?

    Yes exactly,, rest everything is perfect,, infinite thanks to you for the help..

    I have done exactly the same what you suggested, didnot change anything.

    Still the partial view is displayed on a separate page.

    Tuesday, August 4, 2020 9:25 AM
  • User1686398519 posted

    Hi nicklibee,

    I can't reproduce your problem, you can provide a screenshot of the problem so that we can better help you.

    Best Regards,

    YihuiSun

    Tuesday, August 4, 2020 9:33 AM
  • User1897897189 posted

    Hereby I have attached the screen shots of the issue.

    On click of "Ok" button, "Family Details" is displayed on a different Page.

    What I want is , i want to display the "Family Details" on the main view page itself.

    Student Info

    Family Details(Partial View)

    Tuesday, August 4, 2020 11:14 AM
  • User1897897189 posted

    Hellom,
    I have one more doubt.

    If there are multiple controllers and multiple partial views, how can I return the data to partial views?

    Example

    [HttpPost]
    public async Task<ActionResult> IndexAsync(string Input)
    {

    var c = new MController();
    var MData = Task.Run(() => c.M(Input));


    var d = new DController();
    var dData = Task.Run(() => d.M(Input));


    await Task.WhenAll(MData,dData);


    var result = MData.Result as ViewResult;
    var result1 = dData.Result as ViewResult;

    return PartialView("~/Views/M/_MServices.cshtml", result.Model);///how can i return data to
    multiple partial views??
    }


    Thanks
    Nick

    Tuesday, August 4, 2020 5:15 PM
  • User1686398519 posted

    Hi nicklibee

    • Still the partial view is displayed on a separate page.
      1. You need to check whether your partial view refers to a certain "Layout". On my partial view I used"@{Layout = null;}".
      2. You can refer to the following picture how to create a partial view.

                     

    • If there are multiple controllers and multiple partial views, how can I return the data to partial views?
      1. You just need to convert all the partial views into strings.
      2. You need to create a List<string> to store all the partial view data.
      3. You need to use jquery to traverse the returned data and add these data to the current view.

    Controller

            [HttpPost]
            public async Task<ActionResult> getpartialViewsAsync(string Input)
            {
                List<string> viewnamelist = new List<string>();
                List<string> partialViewlist = new List<string>();
                var tasks = new List<Task<ActionResult>>();
    
                var c = new MController();
                var MData = Task.Run(() => c.M(Input));
                tasks.Add(MData);
                viewnamelist.Add("~/Views/M/_MServices.cshtml");
    
                var d = new DController();
                var dData = Task.Run(() => d.M(Input));
                tasks.Add(dData);
                viewnamelist.Add("~/Views/D/_DServices.cshtml");
    var resultlist = await Task.WhenAll(tasks); for (int i = 0; i < resultlist.Count(); i++) { var result = resultlist[i] as ViewResult; partialViewlist.Add(RenderRazorViewToString(this.ControllerContext, viewnamelist[i], result.Model)); } return Json(partialViewlist, JsonRequestBehavior.AllowGet); } public static string RenderRazorViewToString(ControllerContext controllerContext,string viewName, object model) { controllerContext.Controller.ViewData.Model = model; using (var stringWriter = new StringWriter()) { var viewResult = ViewEngines.Engines.FindPartialView(controllerContext, viewName); var viewContext = new ViewContext(controllerContext, viewResult.View, controllerContext.Controller.ViewData, controllerContext.Controller.TempData, stringWriter); viewResult.View.Render(viewContext, stringWriter); viewResult.ViewEngine.ReleaseView(controllerContext, viewResult.View); return stringWriter.GetStringBuilder().ToString(); } }

    View

    <input id="inputtest" name="Input" />
    <button id="testpartialviews" type="button">submit</button>
    <div id="showpartialview">
    </div>
    @section scripts{
        <script>
            $('#testpartialviews').click(function () {
                $.ajax({
                    url: '@Url.Action("getpartialViewsAsync", "Test")',
                    type: 'POST',
                    data: {
                        Input:$("#inputtest").val()
                    },
                    success: function (data) {
                        $("#showpartialview").empty();
                        for (var i = 0; i < data.length; i++) {
                            var $newdiv = $("<div id='partialview" + i + "'>" + data[i] + "</div>")
                            $newdiv.appendTo("#showpartialview");
                        }
                    }
                });
            });
        </script>
    }

    Here is the result.

    Best Regards,

    YihuiSun

    Wednesday, August 5, 2020 6:15 AM
  • User1897897189 posted

    Thank you so so much for the help and the support.. I will implement the multiple views and let you know the outcome.

    Now the main issue is with the partial view getting displayed on a separate page.

    I 2 have layout set to null on partial view, still i don't know why it is displayed on a separate page.

    I have no idea..

    I have an index view which is calling the master page and on the index view i using your code to display the partial view. This is what i am doing.

    Figured out what exactly is the problem using F12.

    $('#testpartialviews').click(function ()-----------Uncaught reference error:$ is not defined.

    I have all the jquery libraries referenced on my view page...

    i have jquery-1.10.2.js

    jquery.min.js

    Regards

    Nick

    Wednesday, August 5, 2020 7:22 AM
  • User1686398519 posted

    Hi nicklibee,

    1. I can't reproduce your problem here. If you can give your partial view, layout view and other used code, so that we can better help you.
    2. Uncaught reference error:$ is not defined.
      • This error occurs because your jquery file was not loaded successfully, and this is also due to the loading sequence. Can you give a screenshot after using F12 in the browser?

                          

    Best Regards,

    YihuiSun

    Wednesday, August 5, 2020 10:26 AM