Asked by:
Pass dataset from one controller to another controllers async Task fucntion

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.csFollowing 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
NickFriday, 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 selfDo 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.
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
NickTuesday, August 4, 2020 5:15 PM -
User1686398519 posted
Hi nicklibee
- Still the partial view is displayed on a separate page.
- You need to check whether your partial view refers to a certain "Layout". On my partial view I used"@{Layout = null;}".
- 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?
- You just need to convert all the partial views into strings.
- You need to create a List<string> to store all the partial view data.
- 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 - Still the partial view is displayed on a separate page.
-
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,
- 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.
-
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