Return view with ViewModel after ajax call - c#

i call an action from ajax function, get my ViewModel in it and then try to open new view with other ViewModel but redirectToAction and return view aren't working. Other answers i saw only got to opening other view without sending ViewModel with it
ajax call
$("#delete").click(function () {
var model = $("#forma").serialize();
console.log("delete", model);
$.ajax({
url: '#Url.Action("DeleteDevices", "package")',
contentType: 'application/json; charset=utf-8',
dataType: "json",
data: model,
success: function (result) {
}
});
return false;
});
and contorller which does nothing
public ActionResult DeleteDevices(PackageDevicesViewModel viewModel)
{
//model processing here
return View(NewModel);
}

change
data: model,
to
data: JSON.parse(JSON.stringify($("form").serializeArray()))

Related

How to use model binder in .net core mvc with Ajax Post?

I'm new to .net core MVC and am trying to execute an Ajax post similar to .net framework MVC. I'm simply trying to POST a single int value to the controller action below. The Ajax call hits the controller, but the action parameter is always 0. I verified that the correct integer value is being sent in the Ajax request payload. What am I missing?
public class HomeController : Controller
{
public IActionResult Index()
{
return View();
}
[HttpPost]
public IActionResult Ajax_GenerateSecretNum([FromBody]int lower)
{
return Json(new { success = true });
}
$.ajax({
url: '#Url.Action("Ajax_GenerateSecretNum", "Home")',
type: 'POST',
contentType: 'application/json; charset=utf-8',
dataType: 'json',
data: { lower: lower },
success: function (response) {
}
});
You could create a model (DTO) for the controller parameter and use JSON.stringify() on your data before posting to the controller.
$.ajax({
url: '#Url.Action("Ajax_GenerateSecretNum", "Home")',
type: 'POST',
contentType: 'application/json; charset=utf-8',
dataType: 'json',
data: JSON.stringify({ lower: lower }),
success: function (response) {
}
});
public class ModelDto
{
public int Lower { get; set; }
}
[HttpPost]
public IActionResult Ajax_GenerateSecretNum([FromBody]ModelDto model)
{
// model.Lower should contain your int
return Json(new { success = true });
}
$.ajax({
url: '#Url.Action("Ajax_GenerateSecretNum", "Home")',
type: 'POST',
data: { "lower": lower, "upper": upper },
success: function (response) {
}
});
Changing my jQuery ajax to the above sample solved the issue. I'm not sure why, but it looks like specifying the extra ajax parameters caused the values to fail model binding. After changing the ajax, I was also able to remove the [FromBody] attribute from the controller action.
You can do something like below:
$.ajax({
method: "POST",
data: { "Property1": "value1", "Property2": "value2"},
url: "#Url.Action("Ajax_GenerateSecretNum", "Home")",
success: function (data) {
//success login
},
error: function (data) {
alert('error' + data.status);
}
});
Controller will look like below:
[HttpPost]
public ActionResult Ajax_GenerateSecretNum(ModelClass modelClass)
{
//You logic will be here
}

Using Ajax to POST to ASP.Net controller - Data for Post incorrect

This is my DisputeController method stub:
[HttpPost]
public virtual ActionResult UpdateDisputeStatus(DisputeUdpateStatusModel model)
{//some code
Here is my Ajax call:
var url = '/dispute/UpdateDisputeStatus';
var disputeStatusObj = {
DisputeId: id,
DisputeStatusId: selectedValue
}
$.ajax({
url: url,
cache: false,
type: 'POST',
contentType: "application/json; charset=utf-8",
data: disputeStatusObj,
success: function (data) {
alert('Status Changed Successfully');
},
error: function (e) {
alert('Error: ' + e.status);
}
});
I know the routing works, as without using the data parameter the code enters my method (obviously without the model in parameters)
I have tried the following data formats:
data: {'DisputeId': DisputeId, 'StatusId': DisputeStatusId},
data: {disputeStatusObj},
data: JSON.Stringify(disputeStatusObj)
using controller methods:
[HttpPost]
public virtual ActionResult UpdateDisputeStatus(string disputeId, string statusId)
[HttpPost]
public virtual ActionResult UpdateDisputeStatus(modelname model)
None of which work. I get Not found errors or 500's.
Bearing in mind that I know the routing is correct, when I send the request with no data, so what am I missing here?
Am I declaring the controller incorrectly?
Verify your model that should be the same name as well as the data type because of while post the value from Jquery that values are not mapping with the property of the model.
#Mike I tried below code
public class DisputeUpdateStatusModel
{
public string DisputeId { get; set; }
public string DisputeStatusId { get; set; }
}
public class DisputeController : Controller
{
[HttpPost]
public virtual ActionResult UpdateDisputeStatus(DisputeUpdateStatusModel model)
{
return new ContentResult() { Content = "OK" };
}
}
script on view as:
<script type="text/javascript">
var disputeStatusObj = {}
disputeStatusObj.model = {
DisputeId: 1,
DisputeStatusId: 1
}
var url = '/dispute/UpdateDisputeStatus';
$.ajax({
url: url,
cache: false,
type: 'POST',
contentType: "application/json; charset=utf-8",
data: JSON.stringify(disputeStatusObj),
success: function (data) {
alert('Status Changed Successfully');
},
error: function (e) {
alert('Error: ' + e.status);
}
});
</script>
Please see.
If this is not working, can you please show Model class?
thanks for all your input. My solution was a combination of the answers above.
I was unable to get my code to model bind, so I went back to basics.
I took out the contentType: "application/json; charset=utf-8", as suggested by Stephen Muecke, and ditched the model in my controller and replaced it with string disputeId, string statusId and as suggested by Er Pravin Suthar ensured the parametes were called the same thing. Also to note, the data section was sent as data: { disputeId: disputeId, statusId: statusId } with no quotes around the parameter names. So I ended up with:
var statusId = statusDropdown.value;
var disputeId = $("#disputeId").val();
$.ajax({
url: "/Dispute/UpdateDisputeStatus",
data: { disputeId: disputeId, statusId: statusId },
type: 'POST',
success: function (data) {
alert('Success');
},
error: function (e) {
alert('Status not changed' + e.responseText + ' : ' + e.status);
}
});
and the Controller structure is:
[HttpPost]
public virtual ActionResult UpdateDisputeStatus(string disputeId, string statusId)
Thanks Again for all your input!

Pass whole Model through ajax call

Is it possible to pass a whole Model through my jQuery's ajax call?
For know I can only get it working if i set one variable at the time.
As the code shows I pass the iVideo_ID through the ajax call. The Video object has a lot of other fields. So instead of writing all the attributes, can i pass the whole existing object (Video Model)?
$.ajax({
type: "POST", //HTTP POST Method
url: "/Video/UpdateComment", // Controller/View
data: { //Passing data
iVideo_ID: '#(Model.Video.iVideo_ID)'
}
});
I have tried with this but it just return a Model that is null:
$.ajax({
type: "POST", //HTTP POST Method
url: "/Video/NyMetode", // Controller/View
data: '#(Model)'
});
So how can i pass the whole model? Is it possible?
EDIT:
My View Model I try to pass:
public class CommentViewModel
{
public List<Comments> Comments { get; set; }
public List<Tasks> Tasks { get; set; }
public Videos Video { get; set; }
public List<VideoTaskScores> VideoTaskScores { get; set; }
}
actually ya you can do that
just change around a bit for more simplification I.e
<script>
var jsonData= #html.raw(json.encode(Model));
then in ajax data
data: modelName : jsonData,
just make sure in your actionresult the param name is also modelName ie
public ActionResult ActionName(model modelName)
Try something like this in your cshmtl page :
<script type="text/javascript">
function GetModel() {
return #Html.Raw(Json.Encode(Model));
}
</script>
And this how you can send WHOLE model:
var ModelData = GetModel();
$.ajax(
{
type: "POST", //HTTP POST Method
url: "/Video/UpdateComment", // Controller/View
data: { ModelName: GetModel(); }
});
You can embed the model properties within a form and then serialize the form and pass it your ajax call.
$.ajax({
url: "/Controller/ActionName",
type: 'POST',
data: $('#MyFormName').serialize()
})
.done(function (response) {
alert(response.Message);
}
}).fail(function () {
alert(Something went wrong);
});
And in the action you can directly access your model as
public ActionResult ActionName(MyModel modelObj)
{}
You can use Json.stringify(model) but before implement this you you should get your Lists of model class with their last states by using jQuery.
Can you try this
// you can get your model data from view by jQuery
// your model has list objects so you should get these from view and add these into model
var model = {...}; // your object corresponds model object
$.ajax({
type: "POST", //HTTP POST Method
url: "/Video/UpdateComment", // Controller/Action
data: Json.stringify(model),
contentType: "application/json"
}).done(function (res) {
// after done insert your code here
});;

cshtml view not rendering

I am using ASP.net MVC with the razor engine.
I have a page with a button, when the button is clicked i call an ActionResult in my controller using Ajax. The Ajax call:
$.ajax({
type: "GET",
url: "/Home/Review",
success: function (data) {
//alert("yay");
}
});
My ActionResult method is hit fine, however it does not load the view speified.
The code:
public ActionResult Review()
{
return View();
}
The current view is Index.cshtml when Review() is hit i would like Review.cshtml to be rendered on screen. (It should be rendered as a full view, not as partial view inside Index.cshtml)
I have tried - return View("Review"); return View("Review.cshtml"); return View("..\Views\Home\Review.cshtml);
I can't use - tml.BeginForm("Action", "Controller", FormMethod.Post); (see my other question MVC submit button not firing)
Write the response directly to the screen
success: function (data) {
document.write(data) }
After ajax, you should render a partial view to add returning result to main view(index).
Index.cshtml
$.ajax({
type: "GET",
url: "/Home/Review",
success: function (data) {
$("#container").html(data);
//alert("yay");
}
...
<div id="container"></div>
Controller
public ActionResult Review()
{
return PartialView();
}
If you want to redirect after ajax you can use something like following:
Index.cshtml
$.ajax({
type: "GET",
url: "/Home/Review",
success: function (data) {
window.location.href = data.url;
}
...
Controller
public ActionResult Review()
{
return Json(new { url = "some url" }, JsonRequestBehavior.AllowGet);
}

ViewModel - repopulate form with new content after ajax requests

When I call an AJAX Get/Post, I can send a ViewModel of my form to my Controller methods. Is there a way to repopulate the form after this request with the new values of the ViewModel? What the right return of my method: a Json with the ViewModel or a View? Like this:
$.ajax({
dataType: "JSON",
data: $('#form').serialize(),
type: "GET",
url: "SomeController/doSomething",
success: function(myViewModel) {
// How to repopulate my form with the new values?
}
});
public class SomeController {
[HttpGet]
public ActionResult DoSomething(MyViewModel model) {
model.SomeProperty = "This property needs to be changed into the View.";
// The right way is returning a Json with the ViewModel...
return Json(model, JsonRequestBehavior.AllowGet);
// or return some View?
return View(model);
}
}
What will be returned is HTML. Can I suggest that you return a PartailView(model), this way it can be used throughout the system, you do not need to json encode it just use return PartialView(model). Put the Partial View in your Shared Folder.
public ActionResult DoSomething(MyViewModel model) {
model.SomeProperty = "This property needs to be changed into the View.";
return PartialView("MyPartialView", model);
}
Change the ajax to stringify the form, this will allow the model binding to work:
$.ajax({
dataType: "JSON",
data: JSON.stringify({model : $('#form').serialize() }),
type: "GET",
url: "SomeController/doSomething",
success: function(myViewModel) {
$('#myUlDropDownListID').replaceWith(myViewModel);
}
});
In your ajax you need to replace the HTML with the return, in this case you have called in myViewModel. I.e. if it is a table then you would do
$('#myUlDropDownListID').replaceWith(myViewModel);
This will replace the table with the new HTML

Categories