Passing a knockout array of objects to an mvc controller action - asp.net-mvc

Folks,
Can anyone help me or direct me to an example of a knockout viewmodel which contains an array of objects being passed to an asp.net mvc action? The only examples I have seen show just simple arrays of strings being passed.
Thanks

Here's an example from the official Knockout site. It's a Contacts editor build with nested arrays. [jsFiddle].
A fitting ASP.NET MVC Action could look like
public ActionResult SaveContacts(IEnumerable<Contact> contacts)
Where Contact is defined as the class:
public class Contact
{
public string firstName { get; set; }
public string lastName { get; set; }
public IEnumerable<Number> phones { get; set; }
}
Where Number is defined as the class:
public class Number
{
public string type { get; set; }
public string number { get; set; }
}
Given the JavaScript Knockout View Model from the example. Your save method could look like this
self.save = function() {
var jsonString = ko.mapping.toJSON(this.searchParams);
$.ajax({
url: "/MyController/SaveContacts",
data: jsonString,
type: 'POST',
contentType: 'application/json',
dataType: 'json'
});
};

Related

Function gets null value from one of the parameters from ajax call

I want to send 2 parameters with data: using ajax. One of the params is a string, and that one always comes out on the c# side as it should, but the second parameter that is an object that consists of few strings and ints, always comes empty to the function.
$.ajax({
url : "/Clients/Create",
data: { client : client, country : country},
method : "post"
});
The interesting part is that when debugging the js file from browser, the debugger says that the objects contain all they should.
public void Create(Client client, string country)
{
//creates...
}
Country param comes out right, but all of the clients values are either null or 0. I tried swapping their places to see if it has something to do with order, no luck there. Also I tried multiple ways to do "data: { client : client, country : country},".
Client class:
public class Client
{
public int Id { get; set; }
public string Name { get; set; }
public string Address { get; set; }
public string City { get; set; }
public int Zip { get; set; }
public int CountryId { get; set; }
public Client() { }
}
This is how I'm building the object of a client in js.
var client = {
Name : name,
Address : address,
City : city,
Zip : zip
}
i suggest you if Client is a mvc model
var client = $.parseJSON('#Html.Raw(Json.Encode(yourModelClient))');
car country = "country";
var dataPlus = {
client : JSON.stringify(client),
country: country
};
ajax
$.ajax({
url: '#Url.Action("Create", "Client")',
data: dataPlus,
method : "POST",
});
then controller
[HttpPost]
public actionresult Create(Client client, string country)
{
}

Passing AngularJS Model to Web API, Model is Null

In need of some advice, I am trying to create a register/login section on a SPA project I am working on.
I am using AngularJS for the front end and MVC Web API for the back end.
Problem I am having is my model is showing as null when the Web API's POST method is hit.
Here is my code:
AngularJS Controller
SugarGlidersMain.controller('RegisterController', ['$scope', 'UserService', '$location', '$rootScope', 'FlashService', function ($scope,UserService, $location, $rootScope, FlashService) {
$scope.user = [{ID:'',Username:'',Password:'',Email:'',LastLogin:'',Role:'User', FirstName:'',LastName:''}]
$scope.register = function() {
var data = $scope.user;
UserService.Create($scope.user)
.then(function (response) {
if (response.success) {
FlashService.Success('Registration successful', true);
$location.path('/login');
} else {
FlashService.Error(response.message);
}
});
}
Note: Firstname, Lastname, Password and Email are bound to input fields in the html
AngularJS service
function Create(user) {
return $http.post('/api/User', user).then(handleSuccess, handleError('Error creating user'));
}
Note: user contains data when being sent to the Web API
WebAPI
// POST api/user
public void Post([FromBody]UserModel user)
{
string firstname = user.FirstName;
string lastname = user.LastName;
}
MVC Model
public class UserModel
{
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int ID { get; set; }
[Required]
public string Username { get; set; }
[Required]
public string Password { get; set; }
[Required]
public string Email { get; set; }
public DateTime? LastLogin { get; set; }
public string Role { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
Does the data structure matter when passing a model to web API eg could I simply pass over Username, Email and Password without the other properties to the Web API and still use UserModel?
Thank you in advance.
In you current case you are passing $scope.user array to post but the thing is though you passed whole data in the array first element controller method won't understand that object, because its different than what actually the method is expecting. So for getting correct object on server you should pass correct JSON.
When you are passing object to API it should pass single user object rather than passing the whole array
UserService.Create($scope.user[0])
OR
Better change user object declaration to object
$scope.user = {ID:'',Username:'',Password:'',Email:'',LastLogin:'',Role:'User', FirstName:'',LastName:''};

How to post a json object from to an mvc action

I have a mvc action
[HttpPost]
public ActionResult EditUser(ApplicationUser model)
ApplicationUser class is:
public class ApplicationUser
{
public int UserId { get; set; }
[Required]
public string UserName { get; set; }
public byte[] HashedPassword { get; set; }
public bool IsActive { get; set; }
public bool IsVerified { get; set; }
}
In jquery side I am doing:
$.ajax({
method: 'POST',
url: '#Url.Content("~/UserAdmin/EditUser")',
dataType: "json",
data: ....How do I post the object...???
});
My question is how do I post the Json object to the method as I hit the break point but the object is null.
Use JSON.stringify to reliably convert your JS object to JSON data for sending across the wire
var user = {
UserId: '31750',
UserName: 'chugh97',
HashedPassword: '...',
IsActive: true,
IsVerified: true
};
...
dataType: 'json',
data: JSON.stringify(user),
...
Note - I would recommend making your HashedPassword a string type instead of a byte[], it would be easier to deal with that client-side.

Receiving HTML-encoded values from asp.net mvc web api

I'm fairly new to MVC web api, and trying to get POST requests to process properly. It's mostly working, but string values are HTML-encoded. I thought this would be handled automatically, and I find no way to do this manually.
Here is the ajax request:
$.ajax({
url: '/api/PulseStudies/UpdateTask',
type: 'POST',
data: { 'userID': userid, 'taskID': CurExamTaskID, 'comment': comment, 'complete': complete },
async: true,
...
Here is the server-side API:
[HttpPost]
public HttpResponseMessage UpdateTask(TaskResponse value)
{
Tasks.UpdateTask(value.userID, value.taskID, value.comment, value.complete);
return Request.CreateResponse(HttpStatusCode.NoContent);
}
public class TaskResponse
{
public int userID { get; set; }
public long taskID { get; set; }
public string comment { get; set; }
public bool complete { get; set; }
}
The comment value is HTML-encoded, e.g., "blah%20blah". How do I get a properly decoded value?
I believe you mean it is UrlEncoded. On the server side you want HttpServerUtility.UrlDecode() http://msdn.microsoft.com/en-us/library/6196h3wt(v=vs.110).aspx to get it back.

Web Api call is returning a 404 error with GUID passed as param

I am having troubles with my ajax call making it to my web.api method. If I remove the Guid orderId from both the api and the js, the call makes it to the controller, but the pizza object is empty. If I pass the Guid in the URL, it also makes it to the controller but no pizza. Please explain why this doesn't work or help me make it work.
JS:
var savePizza = function (orderId, pizza) {
var dataCall = $.ajax(config.savePizzaUrl, {
data: ko.toJSON({ orderId: orderId, pizza: pizza }),
type: "post",
contentType: "application/json"
});
return Q.when(dataCall);
};
Web Api:
[HttpPost]
public RequestReturn<Guid> SavePizza(Guid orderId, Pizza pizza)
{
return PizzaRequests.SavePizza(orderId, pizza);
}
JS Objects:
var pizza = function (data) {
this.Id = data.Id;
this.Size = new size(data.Size);
this.SizeId = data.SizeId;
this.Toppings = $.map(data.Toppings, function(item) {return new topping(item);});
};
var topping = function (data) {
this.Id = data.Id;
this.Name = data.Name;
this.Price = data.Price;
};
var size = function (data) {
this.Id = data.Id;
this.Name = data.Name;
this.Price = data.Price;
};
C# Objects:
public class Pizza
{
public Guid Id { get; set; }
public Guid SizeId { get; set; }
public Size Size { get; set; }
public IEnumerable<Topping> Toppings { get; set; }
}
public class Size
{
public Guid Id { get; set; }
public string Name { get; set; }
public double Price { get; set; }
}
public class Topping
{
public Guid Id { get; set; }
public string Name { get; set; }
public double Price { get; set; }
}
JSON Fiddler Post Capture:
ASP.NET Web API, by default, binds request body to a complex type (Pizza, in your case). Web API binds the body in its entirety to one parameter. Simple types such as GUID are bound from the URI path and query string. So, by passing GUID in the URI and posting only the JSON corresponding to pizza object (only the pizza and not anything else such as order ID), you can get this working.
In my experience the WEB API 2 HttpPost does not work if I try to put a Guid in the parameter collection. I have to put the Guid into the URI, e.g.
var url = window.applicationBaseUrl + "aiapps/"
+ GuidOrderId + "/DeleteByGroupId";
And then the ApiController like this
[HttpPost]
[Route("~/aiapps/{guid:Guid}/deletebygroupid")]
public AiAppsOpResult DeleteByGroupId(Guid guid)
{
Some have suggested that it will work to use a JSON object for the Guid that has an empty key, e.g. {'':OrderId} but not for me. And it does no good to declare the Guid parameter optional or nullable in the controller.
I have not tested #Badri's solution, but I think it will work. I do know the WEB API will work if I make a C# DTO that contains both the Pizza and the OrderIdGuid and POST that, e.g.
public class MetaPizza
{
public Pizza pizza {get;set;}
public Guid OrderId{get;set;}
}
and
[Route("~/api/postorder")]
[HttpPost]
public AiAppsOpResult CalcRisk(MetaPizza metaPizza)
$.ajax({
type: "POST",
dataType: "json",
contentType: "application/json",
url: window.applicationBaseUrl + "api/postorder" ,
data: _JSON_MetaPizza
})

Resources