I have the following JQuery code in my .cshtml file.
$.ajax({
type: "POST",
url: urlPath,
dataType: 'json',
contentType: 'application/json',
data: JSON.stringify({ pendingList: pendingList })
}).error(function (err) {
alert("Error " + err.status);
});
The pendingList object populates with correct values.I could see the values in the post request.
Request Data View
My ASP.NET Controller
[HttpPost]
public ActionResult CreateMultiRequest(List[] pendingList)
{
But I see null for the pendingList.Any help appreciated.
You're posting JSON that looks like:
"pendingList": {
//...
}
Thus, .Net is trying to bind the posted data to an object shaped like:
class SomeType
{
public List[] SomeOtherType { get; set; }
}
Instead, just call JSON.stringify(pendingList) which will send:
{
//...
}
You don't need to send a named object to the ASP .Net controller. It already expects the format of the object to match the type of parameter in the controller method.
There are two ways to fix this.
One:
Just like suggested in other answers use a generic list of type
[HttpPost]
public ActionResult CreateMultiRequest(List<PnedingList> pendingList)
Two:
Use FromBody attribute to help the runtime to retrieve the object from request body
[HttpPost]
public ActionResult CreateMultiRequest([FromBody]List[] pendingList)
Related
I tried to pass more than one parameter from client-side using jQuery to ASP Web API method, but the method can't accept that. I tried some of the solutions but the same thing.
Web API:
[HttpPost]
[ResponseType(typeof(Message))]
[Route("api/Messages/send-message")]
public async Task<IHttpActionResult> SendMessage(Email email, Message message){}
jQuery:
$.ajax({
url: '/api/Messages/send-message',
method: 'POST',
contentType: "application/json; charset=utf-8",
dataType: "json",
data: JSON.stringify({
email: EmailsArray,
title: $('#txtTitle').val(),
body: $('#txtContent').val(),
}),
success: function (response) {
console.log(response);
});
Error Message:
"message":"An error has occurred.","exceptionMessage":"Can't bind multiple parameters ('email' and 'message') to the request's content.","exceptionType":"System.InvalidOperationException"
If you're sending the data as JSON then all the data needs to be contained in a single coherent JSON structure. Having two separate input parameters on the server side does not fit with this concept.
In this situation you can create a DTO (Data Transfer Object) which is a class holding all of the items you want to transfer. Something like this:
public class EmailMessageDTO
{
public Email email { get; set; }
public Message message { get; set; }
}
Then you define the action method as accepting this single over-arching object
public async Task<IHttpActionResult> SendMessage(EmailMessageDTO dto) { }
And in the JavaScript:
data: JSON.stringify({
email: EmailsArray,
message: {
"title": $('#txtTitle').val(),
"body": $('#txtContent').val(),
}
}),
It's quite similar to the concept of having a ViewModel in MVC.
You need to add [FromBody] attribute to parameter and you need to make post data to application/x-www-form-urlencoded and you send only email parameter, you need to add message parameter if you wanna send title and body you need to create model like
model:
public class EmailSendModel(){
public string email{get;set;}
public string title{get;set;}
public string body{get;set;}
}
controller:
[HttpPost]
[ResponseType(typeof(Message))]
[Route("api/Messages/send-message")]
public async Task<IHttpActionResult> SendMessage([FromBody]EmailSendModel model){}
I'm developing an application using asp.net, mvc6 and angularjs on my angular service. When I make a request to an action method, I get no passed data.
When I have checked the request, I could see an exception that caused by:
Form '((Microsoft.AspNet.Http.Internal.DefaultHttpRequest)this.Request).Form'
threw an exception of type
'System.InvalidOperationException' Microsoft.AspNet.Http.IFormCollection
{System.InvalidOperationException}
exception message saying "Incorrect Content-Type:application/json;charset=UTF-8"
my angular service
return $http({ method: 'POST', url: 'home/createEvent', eventDetails: event })
.success(function(data, status, headers, config) {
return data;
})
.catch(function(data, status, headers, config) {
console.log(data);
});
on my controller
[HttpPost]
public IActionResult CreateEvent([FromBody]Event eventDetails)
{
return Json(new {dsd=""},
new JsonSerializerSettings {ContractResolver = new CamelCasePropertyNamesContractResolver()});
}
The accepted answer didn't work for me. For me, the solution was to add a header to the $http call:
$http({
url: "/install",
method: "POST",
data: data,
headers: {
"Content-Type": "application/x-www-form-urlencoded"
}
})
.success(...);
Hope the following examples helps you.
Try to decorate your controller with
[Produces("application/json")]
[Route("api/[controller]")]
Since you din't show your controller name I will give you a fictitious full working example
controller
[Produces("application/json")]
[Route("api/[controller]")]
public class DashBoardLayoutApi : Controller
{
public DashBoardLayoutApi()
{ }
[HttpPost]
public void Post([FromBody] LoginViewModel data)
{ }
}
C# viewmodel
public class LoginViewModel
{
public string Email { get; set; }
public string Password { get; set; }
}
HTML/JS
<script>
var data = {
Email: 'Test',
Password: 'Test',
RememberMe: true
};
$("#test").click(function() {
$.ajax({
url: '/api/DashBoardLayoutApi',
type: 'POST',
dataType: "json",
contentType: "application/json; charset=utf-8",
data: JSON.stringify(data),
});
}
</script>
<button id="test"> Save Layout</button>
Results
In my case, adding [Produces("application/json")] did nothing, but adding the [FromBody] attribute to the parameter is what did the trick!
The hidden's answer is great. However, I still had empty model in C# controller, even after I implemented hidden's approach in my application. After digging around a bit I found that the issue was in incorrect client model created in JS code, which cannot be deserialized on the server (null can not be converted to type Guid).
For some reason, model binder does not throw exceptions in such cases:
https://learn.microsoft.com/en-us/aspnet/core/mvc/models/model-binding
When a parameter is bound, model binding stops looking for values with that name and it moves on to bind the next parameter. If binding fails, MVC does not throw an error. You can query for model state errors by checking the ModelState.IsValid property.
So, check the ModelState.IsValid property in C# controller to make sure you passed valid model and maybe consider using custom model binder to catch model binding errors and log them.
I've tried researching this but I can't find anything anywhere that's helpful or any relevant answers.
For my angular controller I have:
app.controller('AdminCtrl', function ($scope, $http) {
$scope.data = {
Name: '',
Password: ''
},
$scope.login = function (data) {
$http({
method: 'POST',
url: '/login/postlogin',
data: JSON.stringify({
data: $scope.data
}),
contentType: "application/json",
dataType: "json"
}).success(function (data) {
alert('success!');
}).error(function (error) {
alert(error.message);
})
}
});
For my c# controller I have a very basic setup:
[HttpPost]
public string PostLogin(string data) {
return string.Empty;
}
My issue is that inside of the c# controller, data is always null. Does anyone know how to pass the name and password params over to the c# controller? I know for a fact that I am recieving values for them from my textboxes that I have. I am also recieving the success message/alert.Thanks!
Data is not a string. In c# make an object with Name and Password as properties and have this:
[HttpPost]
public string PostLogin(Data data) {
Edit in response to comment:
Yes you need to include the namespace that Data is in in your controller. You could try putting the Data object directly above.
public class Data
{
public string Name { get; set; }
public string Password { get; set; }
}
For clarity, data should not be stringified, instead just sent as data: data
Just send $scope.data directly, dont stringify it. Then modify your PostLogin method so it accepts two strings, one called Name and one called Password.
I have looked at the solutions on the site. i have created two methods one for [HttpPost] and another for [HttpGet] as shown but still i am getting that error message. The code is as shown. but when i make a post request to the server i still get the error.
[HttpGet]
public ActionResult Create()
{
return View();
}
[HttpPost]
public String Create(Customer Customer)
{
/// logic here
return "Done";
}
The current request for action 'Create' on controller type '******Controller' is ambiguous between the following action methods:
System.String Create(Data.Models.***) on type Data.Controllers.UserController
System.Web.Mvc.ActionResult Create(System.Web.Mvc.FormCollection) on type Data.Controllers.UserController i am calling the method from a javascript code as shown below that is when I get the error message.
$.ajax({
url: urlPath + '/Create',
type: 'post',
dataType: 'json',
data: ko.toJSON(this),
contentType: 'application/json',
success: function (result) {
window.location.href = urlPath + '/';
}
Check your error message. These methods are OK as they are. But you have another Create method with FormCollection parameter: Create(System.Web.Mvc.FormCollection). If you don't have that method anymore, maybe you forgot to build your project?
I have seen similar case to mine answered but I have specific need that always differed from others problem.
I am sending json data from my html page to the MVC Web API. Unfortunately the data I am receiving is ALWAYS null (I have tried a lot of different things here). The thing is I really need to received the data as json (string), because my data is very complex and cannot be simply deserialized by the Web API (I have my own custom deserializer that does it).
Heres the code!
First, the web api controller that will receive the ajax post request
public class ActivityController : ApiController
{
// POST api/activity
public string Post([FromBody]string json)
{
}
}
Then, the ajax request itself
$.ajax("/api/activity", {
contentType: "application/json",
data: { json: ko.mapping.toJSON(fusionedModel) },
type: "POST",
success: function (result) {
...
}
});
As far as the data is concerned, it is rendered well (I've used that same request with MVC (not Web Api) and the server was receiving the string perfectly... now for some reason, in my web api controller, the "json" param is ALWAYS null. As I said before, it is IMPORTANT that I receive the data as a json string.
EDIT : I found that my question is a duplicate of this one : POST JSON with MVC 4 API Controller
But I really don't like the answer... having to create an object just to encapsulate the string is very dirty...
I recommend you avoid using standard body parameter binding as that mechanism assumes that you are trying to deserialize the body into a CLR object. Try this,
public class ActivityController : ApiController
{
// POST api/activity
public async Task<HttpResponseMessage> Post(HttpRequestMessage request)
{
var jsonString = await request.Content.ReadAsStringAsync();
return new HttpResponseMessage();
}
}
If you really want to use parameter binding, you can do this.
public HttpResponseMessage Post(JToken jToken)
{
return new HttpResponseMessage()
{
Content = new StringContent(jToken.ToString())
};
}
Please try to use the [HttpPost] Attribute that can be located on System.Web.Http;
public class ActivityController : ApiController
{
// POST api/activity
[HttpPost]
public string Post([FromBody]string json)
{
}
}
I could be wrong here, but it looks like you haven't included your action in the post URL. Try changing
$.ajax("/api/activity", {
contentType: "application/json",
data: { json: ko.mapping.toJSON(fusionedModel) },
type: "POST",
success: function (result) {
...
}
});
To
$.ajax("/api/activity/POST", {
contentType: "application/json",
data: { json: ko.mapping.toJSON(fusionedModel) },
type: "POST",
success: function (result) {
...
}
});