Returning Multiple partial views from single Controller action? - asp.net-mvc-3

I need to update Multiple from an Ajax call , I am confused as in how to return these Multiple views from the Controller Action method.

You can only return one value from a function so you can't return multiple partials from one action method.
If you are trying to return two models to one view, create a view model that contains both of the models that you want to send, and make your view's model the new ViewModel.
E.g.
Your view model would look like:
public class ChartAndListViewModel
{
public List<ChartItem> ChartItems {get; set;};
public List<ListItem> ListItems {get; set;};
}
Then your controller action would be:
public ActionResult ChartList()
{
var model = new ChartAndListViewModel();
model.ChartItems = _db.getChartItems();
model.ListItems = _db.getListItems();
return View(model);
}
And finally your view would be:
#model Application.ViewModels.ChartAndListViewModel
<h2>Blah</h2>
#Html.RenderPartial("ChartPartialName", model.ChartItems);
#Html.RenderPartial("ListPartialName", model.ListItems);

There is a very good example here....
http://rhamesconsulting.com/2014/10/27/mvc-updating-multiple-partial-views-from-a-single-ajax-action/
Create a helper method to package up the partial view...
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();
}
}
Create a controller action to bundle the multiple partial views....
[HttpPost]
public JsonResult GetResults(int someExampleInput)
{
MyResultsModel model = CalculateOutputData(someExampleInput);
var totalValuesPartialView = RenderRazorViewToString(this.ControllerContext, "_TotalValues", model.TotalValuesModel);
var summaryValuesPartialView = RenderRazorViewToString(this.ControllerContext, "_SummaryValues", model.SummaryValuesModel);
return Json(new { totalValuesPartialView, summaryValuesPartialView });
}
Each partial view can use its own model if required or can be bundled into the same model as in this example.
Then use an AJAX call to update all the sections in one go:
$('#getResults').on('click', function () {
$.ajax({
type: 'POST',
url: "/MyController/GetResults",
dataType: 'json',
data: {
someExampleInput: 10
},
success: function (result) {
if (result != null) {
$("#totalValuesPartialView").html(result.totalValuesPartialView);
$("#summaryValuesPartialView").html(result.summaryValuesPartialView);
} else {
alert('Error getting data.');
}
},
error: function () {
alert('Error getting data.');
}
});
});
If you want to use this method for a GET request, you need to remove the [HttpPost] decorator and add JsonRequestBehavior.AllowGet to the returned JsonResult:
return Json(new { totalValuesPartialView, summaryValuesPartialView }, JsonRequestBehavior.AllowGet);

Maybe this solution can help you:
http://www.codeproject.com/Tips/712187/Returning-More-Views-in-an-ASP-NET-MVC-Action

Related

call to function from the controller in index.html

In my mvc app I have combobox, I am trying to do the following: when the user choose some item that will call to some function from the controller.
Index.html:
#using (Ajax.BeginForm("dor", "Home", new AjaxOptions
{
HttpMethod = "Get",
//UpdateTargetId = "myPic",
InsertionMode = System.Web.Mvc.Ajax.InsertionMode.Replace
}))
{
#Html.DropDownListFor(x => x.SelectedFileName, Model.Files, new { Name = "map", #class = "form-control", onchange = "CallChangefunc()" })
}
.
.
.
<script type="text/javascript">
function CallChangefunc() {
window.location.href = '#Url.Action("dor","Home")';
}
</script>
HomeVM:
public class HomeVM
{
public List<SelectListItem> Files { get; set; }
public string SelectedFileName { get; internal set; }
public List<string> DynamicAlgorithems { get; set; }
}
Homecontroller:
public void dor()
{
//some code
}
The problem: when the user choose some item from combobox it redirect me to blank page i.e to http://localhost:55354/Home/dor, but I only want to call the function named dor, not to go to blank page!.
what am I missing?
Related
window.location.href always redirect to a new page URL assigned to it. You should use jQuery.ajax() to call the action method when onchange method triggered and return desired result:
jQuery (inside $(document).ready())
$('#SelectedFileName').change(function() {
var selectedFileName = $(this).val();
$.ajax({
type: 'GET',
url: '#Url.Action("Dor", "Home")',
data: { fileName: selectedFileName },
success: function (result) {
// do something
}
});
});
Controller
[HttpGet]
public ActionResult Dor(string fileName)
{
// do something
}
Note: Make sure that action method argument has same name with assigned data passed from AJAX callback.

Empty data send by json

For unknown reason for me data received by my function in controller is always null.
My data is translated into json properly. Data is send but not received (sending ends with success).
Here You can see my Ajax function
$.ajax({
url: "/Devices/Read",
contentType: "text",
type: "POST",
datatype: "json",
data: ko.toJSON(self),
error: function (xmlHttpRequest, errorText, thrownError) {
console.log("error")
},
success: function (data) {
if (data != null) {
console.log("success");
}
}
});
here my function in controller:
[HttpPost]
public ActionResult Read(string data)
{
return Json(new Object());
}
I tried:
changing parameter type to: Object, String
changing contentType to : text, application/json; charset=utf-8
Still no efects. Can anyone suggest me where should I search for mistake?
UPDATE:
After changing method declaration to:
public ActionResult Read(object[] data, string DeviceUser, string DeviceId, string number)
Last three strings are OK but first object consist of proper number of elements but they are null.
in JS they are alements in array of classes
structure of my JS objects:
var Eq = function (name, price) {
var self = this;
self.DeviceSerialNumber = ko.observable();
self.Batch = ko.observable();
};
var ViewModel = function () {
var self = this;
self.data = ko.observableArray([]);
self.DeviceUser = ko.observable();
self.DeviceId = ko.observable();
self.number = ko.observable(1);
};
In your controller action, why do you:
return RedirectToAction("Index");
I think you may want to:
return Json(data);
If you are writing an HTTP Post method, then the redirect to action does not really make sense, because you are posting data, not requesting a page.
You could do something like this:
[HttpPost]
public ActionResult Read(string Data)
{
return Json(Data);
}
OK problem was in setting proper parameter type in method.
TO solve my problem I need to modify method declaration to:
public ActionResult Read(ViewModel m)
and add ViewModel like this:
public class ViewModel
{
public List<InnerClass> data { get; set; }
public string DeviceUser {get;set;}
public string DeviceId {get;set;}
public int number {get;set;}
}
public class InnerClass
{
public string DeviceSerialNumber { get; set; }
public string Batch { get; set; }
}
now all data is received.
Thanks You all for help and suggestions. I will give you all +1 :)

How to update an MVC partial view with regular Ajax

I have an Ajax form that updates the partial view it's in, but I need it to update a second partial view as well. I'd like to do this without merging them both into one view and updating that.
I think my best bet is to use a regular jQuery Ajax call on the form's onsuccess, but I don't know what parameters to use so I can just call a Controller Action that returns the partial to have it work.
My form is set up with
#using (Ajax.BeginForm("UpdateDateRange",
new { name = Model.Modules[i].Name },
new AjaxOptions { UpdateTargetId = Model.Modules[i].Name.Replace(" ", "_") + "_module" }
))
{ [Input fields] }
In your onSuccessmethod you can make another ajax call.
So for example in your OnSuccessMehtod call "MethodX"...which would do a ajax call and update a div on your page with returned result
var MethodX = function(id)
{
$.get("ActionName?id=" + id, function (result) {
$("#myAnotherdiv").html(result)
}, 'html');
}
In response to ajax call you can send two partial view that you want with this helper:
public static class MvcHelpers
{
public static string RenderPartialView(this Controller controller, string viewName, object model)
{
if (string.IsNullOrEmpty(viewName))
viewName = controller.ControllerContext.RouteData.GetRequiredString("action");
controller.ViewData.Model = model;
using (var sw = new StringWriter())
{
ViewEngineResult viewResult = ViewEngines.Engines.FindPartialView(controller.ControllerContext, viewName);
var viewContext = new ViewContext(controller.ControllerContext, viewResult.View, controller.ViewData, controller.TempData, sw);
viewResult.View.Render(viewContext, sw);
return sw.GetStringBuilder().ToString();
}
}
}
And in controller:
return Json(new { view1 = this.RenderPartialView(...), view2 = this.RenderPartialView(...) });
and in success you can get two partialView and replace them with old ones:
function success(data)
{
$("someSelectorToSelectPartial1").html(data.view1);
$("someSelectorToSelectPartial2").html(data.view2);
}

HttpPost with AJAX call help needed

what else do i need in my code please, I have this so far:
<script type="text/javascript">
function PostNewsComment(newsId) {
$.ajax({
url: "<%= Url.Action("AddCommentOnNews", "Home", new { area = "News" }) %>?newsId=" + newsId + "&newsComment=" + $("#textareaforreply").val(), success: function (data) {
$("#news-comment-content").html(data + $("#news-comment-content").html());
type: 'POST'
}
});
}
$("#textareaforreply").val("");
</script>
and
[HttpPost]
[NoCache]
public ActionResult AddCommentOnNews(int newsId, string newsComment)
{
if (!String.IsNullOrWhiteSpace(newsComment))
{
var currentUser = ZincService.GetUserForId(CurrentUser.UserId);
ZincService.NewsService.AddCommentOnNews(newsId, newsComment, currentUser.UserId);
Zinc.DataModels.News.NewsCommentsDataModel model = new DataModels.News.NewsCommentsDataModel();
var today = DateTime.UtcNow;
model.CommentDateAndTime = today;
model.NewsComment = newsComment;
model.Firstname = currentUser.Firstname;
model.Surname = currentUser.Surname;
model.UserId = CurrentUser.UserId;
return View("NewsComment", model);
}
return null;
}
<div class="actions-right">
<%: Html.Resource(Resources.Global.Button.Reply) %>
</div>
i have no idea how this works, because it is not working in FF???
and the other thing is i must not pass return null i must pass JSON false ???
any help please?
thanks
You should encode your request parameters. Right now you have concatenated them to the request with a strong concatenation which is a wrong approach. There's a property called data that allows you to pass parameters to an AJAX request and leave the proper url encoding to the framework:
function PostNewsComment(newsId) {
$.ajax({
url: '<%= Url.Action("AddCommentOnNews", "Home", new { area = "News" }) %>',
type: 'POST',
data: {
newsId: newsId,
newsComment: $('#textareaforreply').val()
},
success: function (data) {
$('#news-comment-content').html(data + $('#news-comment-content').html());
}
});
}
Also you haven't shown where and how you are calling this PostNewsComment function but if this happens on the click of a link or submit button make sure that you have canceled the default action by returning false, just like that:
$('#someLink').click(function() {
PostNewsComment('123');
return false;
});
and the other thing is i must not pass return null i must pass JSON false ???
You could have your controller action return a JsonResult in this case:
return Json(new { success = false });
and then inside your success callback you could test for this condition:
success: function (data) {
if (!data.success) {
// the server returned a Json result indicating a failure
alert('Oops something bad happened on the server');
} else {
// the server returned the view => we can go ahead and update our DOM
$('#news-comment-content').html(data + $('#news-comment-content').html());
}
}
Another thing you should probably be aware of is the presence of dangerous characters such as < or > in the comment text. To allow those characters I would recommend you build a view model and decorate the corresponding property with the [AllowHtml] attribute:
public class NewsViewModel
{
public int NewsId { get; set; }
[AllowHtml]
[Required]
public string NewsComment { get; set; }
}
Now your controller action will obviously take the view model as argument:
[HttpPost]
[NoCache]
public ActionResult AddCommentOnNews(NewsViewModel viewModel)
{
if (!ModelState.IsValid)
{
var currentUser = ZincService.GetUserForId(CurrentUser.UserId);
ZincService.NewsService.AddCommentOnNews(viewModel.NewsId, viewModel.NewsComment, currentUser.UserId);
var model = new DataModels.News.NewsCommentsDataModel();
var today = DateTime.UtcNow;
model.CommentDateAndTime = today;
model.NewsComment = newsComment;
model.Firstname = currentUser.Firstname;
model.Surname = currentUser.Surname;
model.UserId = CurrentUser.UserId;
return View("NewsComment", model);
}
return Json(new { success = false });
}

How to return IEnumerable values with using ajax in MVC3?

How can I return IEnumerable's values with using ajax. Here is my script:
$.ajax({
type: "get", url: "street", data: { a: value2 },
success: function (data) {
alert(data);
}
And here is my controller method:
[HttpGet]
public string street(string a)
{
EmlakServicesClient client = new EmlakServicesClient();
client.ClientCredentials.UserName.UserName = "service_test";
client.ClientCredentials.UserName.Password = "..";
client.ClientCredentials.ServiceCertificate.Authentication.CertificateValidationMode = System.ServiceModel.Security.X509CertificateValidationMode.None;
Street[] list =client.GetStreet(Convert.ToInt32(a));
return ("" + list.FirstOrDefault().StreetName);
}
As you can see at top I get value but with First Value so how can I get these all values from IEnumarable?
You should use JSON:
return Json(list, JsonRequestBehavior.AllowGet);
You will need to change your action method to return ActionResult.
return the Collection as JSON
public ActionResult GetsomeItems(int someId)
{
var someCollection=GetListOfItemsFromSomeWhere(someId)
return Json(someCollection,JsonRequestBehaviour.AllowGet);
}
I tripped over this while doing a Google search on how to return JSON results using ASP.NET Web API 2. In case someone else is looking for the same solution, here is the solution that worked for me:
// GET: api/Users
public HttpResponseMessage Get()
{
var users = UserManager.Get(); // returns IEnumerable
return Request.CreateResponse(HttpStatusCode.OK, users);
}
You can learn more about HttpResponseMessage here.

Resources