I've seen other posts on this subject and have fiddled with variations but still cannot not get the JSON model binding to work correctly.
I have the following in my global.asax.cs Application_Start method:
ValueProviderFactories.Factories.Add(new JsonValueProviderFactory());
The post back data looks like this:
{"UserName":"Mike","Password":"password","Persist":true}
My PoCo:
public class UserLoginViewModel {
public string UserName { get; set; }
public string Password { get; set; }
public bool Persist { get; set; }
}
The controller method fires properly but has default UserLoginViewModel object with UserName = null, Password = null, and Persist = false; the signature looks like this:
[HttpPost]
public ActionResult Logon(UserLoginViewModel model) {
if (ModelState.IsValid) {
...
The problem is on the client side! I didn't have the contentType set.
$.ajax({
url: location.href,
type: "POST",
data: ko.toJSON(this),
datatype: "json",
**contentType: "application/json charset=utf-8",**
success: function (data) { alert("success"); },
error: function (data) { alert("error"); }
});
Related
I have aspx file which having upload file option.
<input type="file" name="Attachment" />
On submit button i am sending request to MVC controller to save file.
self.SaveVPD = function () {
var emp = { FirstName: 'edfd', SecondName: 'dfdf' };
var data = new VPDModel(emp, self.EvidenceForm());
var jsonData = ko.toJSON(data);
var url = pageUrl + '/Save';
debugger;
$.ajax({
type: "POST",
url: url,
contentType: "application/json; charset=utf-8;",
//contentType: "multipart/form-data",
data: JSON.stringify(data),
//dataType: "json",
success: function (data) {
debugger;
if (data) {
//TODO::PP
}
else {
//TODO::PP
}
},
error: function () {
debugger;
//TODO::PP
}
});
}
My MVC controller is look like
[HttpPost]
public ActionResult Save(VPDModel vpdInfo) //, HttpPostedFileBase Attachment)
//public ActionResult Save(FormCollection collection)
{
if (ModelState.IsValid)
{
}
}
And my model is
public class VPDModel
{
public Employee Employee { get; set; }
public EvidenceForm EvidenceForm { get; set; }
}
EvedenceForm class is
public class EvidenceForm
{
//public string Attachment { get; set; }
public HttpPostedFileBase Attachment { get; set; }
}
When i send the request back to server VPDModel populate with all valid client side data without File Attachment. Its always null.
I have been to couple of article but cannot resolve it. can anyone help and let me know what am i doing wrong in it?
I have an Web Api application with simple controller. Get methods work fine, but i have an issue with post and put requests.
[Route("api/[controller]")]
[EnableCors("AllowAll")]
public class LessonController : Controller {
...
[HttpPut("{id}")]
public void Put(int id, [FromBody] Lesson lesson) {
...
}
....
}
where Lesson is
public class Lesson {
public int Id { get; set; }
public string Name { get; set; }
public string Text { get; set; }
public string Description { get; set; }
public bool IsModerated { get; set; }
public int? PrevLessonId { get; set; }
public int? NextLessonId { get; set; }
}
So i try to send request and have no luck, lesson is just an object with default-initialized properties. I sent request in two way: first with js
$.ajax({
type: "POST",
url: 'http://localhost:1822/api/lesson/1',
data: JSON.stringify({
lesson: {
description: "Fourth lesson description",
isModerated: true,
name: "Fourth lesson",
nextLessonId: 5,
prevLessonId: 3,
text: "Fourth lesson text"
}}),
contentType: "application/json",
success: function (data) {
alert(data);
}
});
and with Postman:
So the content type is correct. Can anyone tell me what problem is connected with?
UPD:
I have tried to use PostLesson model, that contains all properties from Lesson but Id and sent request via Postman with UpperCamelCase data in body, but it does not solve my problem.
I have solved my own issue. In fact the problem is pretty simple.
We just need to pass object in Post method that equals of structure of Lesson model without specify argument name. So my js code need looks like
$.ajax({
type: "POST",
url: 'http://localhost:1822/api/lesson/1',
data: JSON.stringify({
description: "Fourth lesson description",
isModerated: true,
name: "Fourth lesson",
nextLessonId: 5,
prevLessonId: 3,
text: "Fourth lesson text"
}),
contentType: "application/json",
success: function (data) {
alert(data);
}
});
For some addition information see this link.
I sent an object to controllers action thorugh ajax , but I don't know how to recevie the object in controller. My ajax call is :
$.ajax({
type: "POST",
url: '#Url.Action("Create","Home")',
data: { ID: '#Model.ID', Name: '#Model.Name'}
}).done(function (msg) {
alert("Added :" + msg);
});
This should work , BUt I can't figure out how to recevie the object in controller. I wrote this :
public ActionResult Create(Home h)
{
}
But it is not working . I neeed help in this , Thanks in advance.
My Home class :
public class Home
{
public int ID { get; set; }
public string Name { get; set; }
}
Your action should be like thus:
[HttpPost]
public ActionResult Create(Home h)
{
throw new NotImplementedException(); // put you code here
}
I have an MVC view model that looks like this:
public class DirectorySearchModel
{
[Display(Name = "First name contains")]
public string FirstName { get; set; }
[Display(Name = "Last name contains")]
public string LastName { get; set; }
public CountriesCollection Countries { get; set; }
public IEnumerable<Country> SelectedCountries { get; set; }
public IEnumerable<Country> AllCountries { get; set; }
}
The CountriesCollection object (line 9) looks like this:
public class CountriesCollection
{
[Display(Name = "Countries")]
public int[] arrCountries { get; set; }
}
Now, I'm creating a new, blank instance of CountriesCollection and then adding it to a blank instance of the DirectorySearchModel view model and then serialising it all into a javascript view model for Knockout.js:
{
"FirstName":null,
"LastName":null,
"Countries":{"arrCountries":[]},
"SelectedCountries":[{"RelationshipManager":{},"CountryId":1,"CountryName":"UK"},{"RelationshipManager":{},"CountryId":2,"CountryName":"France"},{"RelationshipManager":{},"CountryId":3,"CountryName":"Spain"}],
"AllCountries":[{"RelationshipManager":{},"CountryId":1,"CountryName":"UK"},{"RelationshipManager":{},"CountryId":2,"CountryName":"France"},{"RelationshipManager":{},"CountryId":3,"CountryName":"Spain"}]
}
My checkboxes are rendered as: <input checked="checked" data-bind="checked: Countries.arrCountries" id="Countries_arrCountries30" name="Countries.arrCountries" type="checkbox" value="1">. Checking a couple means you end up with this Knockout.js view model:
{
"FirstName":null,
"LastName":null,
"Countries":{"arrCountries":["1", "3"]},
"SelectedCountries":[{"RelationshipManager":{},"CountryId":1,"CountryName":"UK"},{"RelationshipManager":{},"CountryId":2,"CountryName":"France"},{"RelationshipManager":{},"CountryId":3,"CountryName":"Spain"}],
"AllCountries":[{"RelationshipManager":{},"CountryId":1,"CountryName":"UK"},{"RelationshipManager":{},"CountryId":2,"CountryName":"France"},{"RelationshipManager":{},"CountryId":3,"CountryName":"Spain"}]
}
Submitting my view normally (i.e. via a submit button and not with Knockout.js) to an MVC action that expects a DirectorySearchModel, I'm able to ask for model.Countries.arrCountries to get a list of the checked items, but when I use...
$.post("/MyController/MyAction", ko.toJS(viewModel), function(returnData) {
$("#resultCount").html(returnData);
});
or...
$.post("/MyController/MyAction", viewModel, function(returnData) {
$("#resultCount").html(returnData);
});
to another action that expects the same DirectorySearchModel, model.Countries.arrCountries is always null! I wondered if it's due to Knockout.js posting the arrCountries entries as string[]s when MVC is expecting int[]s, but changing my MVC code to expect string[]s doesn't seem to change much..! The CountriesCollection object within the DirectorySearchModel appears to exist, but it's the arrCountries within that's always null.
Any ideas? Any help much appreciated!
Edit
The action that receives the Knockout.js viewModel:
public MvcHtmlString ResultCount(DirectorySearchModel model)
{
return new MvcHtmlString(getResultCount(model).ToString());
}
The getResultCount method:
public int getResultCount(DirectorySearchModel model)
{
IUserRepository userRepository = new UserRepository();
int count = userRepository.Search(model, null).Count();
return count;
}
FIXED!
Thanks to Konstantin for pointing out that a simple switch from $.post to $.ajax to send my Knockout.js view model back to my mvc action was all that was needed! Here's the $.ajax code I'm using:
$.ajax({
type: "POST",
url: "/MyController/MyAction",
data: ko.toJSON(viewModel),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (data) {
$("#resultCount").html(data);
}
});
You cant use $.post you need to go for the underlying $.ajax and add the correct contenttype to make mvc accept the posted json and do the model binding (contenttype should be "application/json; charset=utf-8") google for it and you will se lots of examples
I am trying to send AJAX POST request to an MVC Application
$.ajax({
type: 'POST',
dataType: 'json',
data: {"FirstName":"chris","LastName":"cane"},
contentType: 'application/json',
url: "http://dev.irp.com/irp.Ajax.Search/home/Foo",
success: function (data) {
alert(data);
}
});
This script is present on a different server on an ASP.NET application. My MVC App to handle the code is as below
[HttpPost]
public JsonResult Foo(fromclient test)
{
var obj = new SearchMemberServiceClient();
var members = obj.FindMember(test.FirstName, test.LastName, "", "", "", "").Members;
IEnumerable<Bar> sorted =
from a in members
orderby a.FirstName ascending
group a by new
{
a.FormattedFullName,
a.MembershipsProxy[0].GoodFromDate,
a.MembershipsProxy[0].GoodThroughDate,
} into k
select new Bar
{
FormattedName = k.Key.FormattedFullName,
goodfrom = k.Key.GoodFromDate,
goodthru = k.Key.GoodThroughDate,
};
return Json(sorted.ToList());
}
public class Bar
{
public string FormattedName { get; set; }
public DateTime goodfrom { get; set; }
public DateTime goodthru { get; set; }
}
public class fromclient
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
The problem is the script needs to post to that url and get the json data. But as the controller does not have any view, When I look inside the console on the client side it says 404 error for the url and also it says XMLHttpRequest cannot load http://dev.irp.com/irp.Ajax.Search/home/Foo. Origin http://web-dev.irps.com is not allowed by Access-Control-Allow-Origin.
I dont know if the problem has to do with the absolute path of the url for ajax request. If so how could I overcome this?
Due to the same origin policy restriction that't built into browsers you cannot send AJAX requests to different domains. A possible workaround is to have the server return JSONP instead of JSON. Here's an example of a custom JsonpResult that you could use in your controller action.
Can U try JSONP ? Why json? It's perfect to cross-domain.