I am trying to call an Web API which is in aspnet core
Problem is , the number of parameters are not fixed in this. Parameter can be 2 or 10 ( no of parameters will be between 0 to 15 , a guess )
Below is JS code
$(function () {
$('#btn').click(function () {
var src = [
{
"Question1": "Answer1",
"Question2": "Answer2",
"Question3": "Answer3",
"Question4": "Answer4",
"Question5": "Answer5"
}
];
$.ajax(
{
url: 'api/Default/',
method: 'POST',
dataType: 'JSON',
data: JSON.stringify(src),
contentType: "application/json",
success: function (d) {
alert("Success");
},
error: function (e) {
alert("Error please try again");
}
});
})
})
And API
[Produces("application/json")]
[Route("api/Default/")]
public class DefaultController : Controller
{
[HttpPost]
public JsonResult apc(string [][] s)
{
string str;
//Code Here
return Json(true);
}
}
I also tried adding a list of class as parameter instead of string array
public class param
{
public string key { get; set; }
public string Value { get; set; }
}
But Parameter value is always null.
I used the same concept in MVC5 and it works perfectly there but not working in .Net Core
How can we send multiple parameter here ??
Because of the dynamic nature of the data to be posted you can use an array of Dictionary
[Produces("application/json")]
[Route("api/Default/")]
public class DefaultController : Controller {
[HttpPost]
public JsonResult apc([FromBody]Dictionary<string,string>[] data) {
var value = data[0]["Question1"]; // Should be "Answer1"
//Code Here
return Json(true);
}
}
Try to send the JSON as string and send it like bellow :
[HttpPost]
public JsonResult apc(string s)
{
string str;
//Code Here
return Json(true);
}
then handle the json from the .NET side
Related
The javascript side of things looks like this:
var self = this;
self.services = ko.observableArray([]);
self.saveServices = function () {
if (self.services().length > 0) {
var obj = JSON.stringify({ services: self.services() });
$.ajax({
contentType: 'application/json; charset=utf-8',
dataType: 'json',
type: "POST",
url: '/Business/SaveServices',
data: obj,
success: function (data) {
$("#saveModal").modal('show');
if (!data) {
$("#saveDetails").text('Processing error, please try again or email us.');
return;
} else if (data === "saved") {
$("#saveDetails").text('Saved changes.');
setTimeout(function () {
$('#saveModal').modal('hide');
}, 2500);
} else {
$("#saveDetails").text(data);
}
},
error: function (error) {
$("#saveModal").modal('show');
$("#saveDetails").text('Processing error, please try again or email us.');
}
});
}
}
Then my controller looks like this:
[HttpPost]
public async Task<JsonResult> SaveServices([FromBody]SaveServicesRequest saveServicesRequest)
{
try
{
if (User.Identity.IsAuthenticated)
{
return Json("saved");
}
return Json("User is not authenticated.");
}
catch (Exception ex)
{
logger.Error(ex + ". Users Email address: " + User.Identity.Name);
return Json("Processing error, please try again or email us.");
}
}
public class SaveServicesRequest
{
public List<services> services { get; } = new List<services>();
}
public class services
{
public string service { get; set; }
}
Am hitting the controller but the array of items I'm expecting is not returned (saveServicesRequest is empty), I cannot seem to pass an array in any form. Anyone see what am doing wrong? The data/json is being sent client side, think the problem might lie in how am building the json and receiving it.
The problem is that you're initializing services to a new list in SaveServicesRequest. The properties should also have public getters and setters for model binding.
Try updating your class to:
public class SaveServicesRequest
{
public List<services> services { get; set; }
}
this is my first question on SO, so it's probably something basic.
I created a button in order to trigger a method in the Controller via an ajax request.
I am getting this error:
The message cannot be deserialized into MessageContract type FXM.Ordering.WS.Contract.BoCreateAffiliateRequest since it does not have a default (parameterless) constructor.
I tried to modify the ajax request and rechecked all parts of my code but it didn't solve the problem.
My button:
<div class="form-group">
<div>
<input type="button" value="Create" class="btn btn-default" id="create-affiliate-button" />
</div>
</div>
The ajax request:
<script type="text/javascript">
$(function () {
refreshGroups();
$('#create-affiliate-button').click(function (e) {
console.log("blahblahblah");
var b = $("form").serialize();
console.log("formvalues", b);
$.ajax({
url: "/en/AjaxUI/CreateAffiliate",
type: "GET",
dataType: "json",
data: b,
//error: function (jqXHR, exception) {
// failMessage();
//}
});
});
});
function refreshGroups() {
var pltf = "MT4_LIVE";
var out = $('#MT4Group');
if (pltf != null && pltf !== "") {
$.ajax({
url: '/' + window.currentLangCulture + '/BOLiveForms/GetPlatformGroupByFilter',
data: {
platform: pltf, currency: "", withId : true
},
type: 'GET',
beforeSend: function () {
$('#tpLoader').show();
},
complete: function () {
$('#tpLoader').hide();
},
success: function (data) {
populateDropDown(out, data);
}
});
} else {
out.empty();
out.append($('<option></option>').val('').html(window.defaultSelection));
}
}
The method I am trying to call in the Controller
public JsonResult CreateAffiliate(NewAffiliateViewModel newAffiliateViewModel)
{
try
{
var res = BackOfficeServices.BoAddAffiliateUser(newAffiliateViewModel);
return Json("success");
}
catch (Exception e)
{
throw e;
}
}
What am I missing?
Where/How to add this default (parameterless) constructor?
UPDATE after adding the parameterless constructor as suggested.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace FXM.BO.ViewModels
{
public class NewAffiliateViewModel
{
public NewAffiliateViewModel()
{
}
public int Id { get; set; }
public string AffiliateName { get; set; }
public string Email { get; set; }
public int Employee { get; set; }
public int MT4Group { get; set; }
}
}
Add a parameterless constructor to your NewAffiliateViewModel class:
public class NewAffiliateViewModel
{
public NewAffiliateViewModel()
{
}
}
Try use #Url.Action() for this purpose.
$.ajax({
url: "#Url.Action("CreateAffiliate", "AjaxUI")",
type: "GET",
dataType: "json",
data: {
newAffiliateViewModel : b
},
//error: function (jqXHR, exception) {
// failMessage();
//}
});
#EDIT 1:
So you can pass complex objects, like your class. You need to parse JSON inside controller action, and in Action parameter set this:
public JsonResult CreateAffiliate(string newAffiliateJSON)
{
try
{
//here you need to deserizlize variable newAffiliateJSON
//to object try this helper: https://json2csharp.com/
//something like that Root myDeserializedClass = JsonConvert.DeserializeObject<Root>(myJsonResponse); (and you need to create new class, that describes your json (get it on site i write upper))
var res = BackOfficeServices.BoAddAffiliateUser(newAffiliateViewModel);
return Json("success");
}
catch (Exception e)
{
throw e;
}
}
So rewrite JS code and Action method like I said. In ajax request u MUST name data parameters SAME like in controller action
data: { newAffiliateJSON: b}
I'm trying to post a list of objects to a MVC controller via AJAX, but when it gets to the controller the editedPrices parameter is 0.
What am I doing wrong? Currently I'm not sure if the issue is with the data I'm sending or the controller.
Java Script:
$(document).ready(function () {
var newPrices = [
{ "id": "1", "wePrice" : "99", "wdPrice":"79" },
{ "id": "2", "wePrice" :"89", "wdPrice":"59" }
];
editedPrices = JSON.stringify(newPrices);
$.ajax({
contentType: 'application/json; charset=utf-8',
type: "POST",
url: "#Url.Action("EditRates")",
data: {editedPrices : newPrices},
dataType: "json",
success: function (msg) {
alert(msg);
},
error: function (req, status, error) {
alert(error);
}
});
});
c# object
public class EditPrices
{
public string id { get; set; }
public string wePrice { get; set; }
public string wdPrice { get; set; }
}
controller
[HttpPost]
public int EditRates(List<EditPrices> editedPrices )
{
return editedPrices.Count();
}
I've tried using the [FromBody] attribute, but then the editedPrices parameter is null (as opposed to showing a count of 0).
Edit
Just to clarify, I can see that some data is being sent in the AJAX request. And I can see that the controller is being called. So the AJAX request it self is working. But I'm either sending the data in the 'wrong' format, or there's something wrong with how I'm trying to receive it.
You should just change this line:
...
data: JSON.stringify(newPrices),
...
You are making another object with {editedPrices : newPrices}. Your API accepting array.
It seems that ValidateAntiForgeryToken attribute prevents the data from being parsed properly when passed to MVC Controller, the code below works when I remove the ValidateAntiForgeryToken attribute but does not work with it, all the parameters in the controller action are passed except array of translations.
Please advise on how to pass array of objects while utilizing ValidateAntiForgeryToken attribute, is it even possible?
This is my code
C#
[HttpPost]
[ValidateAntiForgeryToken]
public void AddComment( string code, string type, string ecomment, IEnumerable<CommentTranslation> translations)
{
//do something later
}
CommentTranslation is
public class CommentTranslation
{
public string LangId { get; set; }
public string LangName { get; set; }
public string Translation { get; set; }
}
js
addComment: function (ecomment, type, translations) {
var data = {
code: '',
type: type,
ecomment: ecomment,
translations: translations
};
var url = 'CommentsAjax/AddComment';
return comments.repository.postDataWithToken(data, url);
},
postDataWithToken: function (data, url) {
return $.ajax({
type: 'POST',
traditional: true,
contentType: 'application/x-www-form-urlencoded; charset=utf-8',
data: comments.repository.addAntiForgeryToken(data),
url: getServerPath() + url
});
}
addAntiForgeryToken: function (data) {
var token = $('input[name="__RequestVerificationToken"]').val();
data.__RequestVerificationToken = token;
return data;
},
Ended up using FormCollection that you can just generically pass anything into the Controller.
I'm using the USDA food database to try to make an app that will tell you if you've gotten your daily recommendations of vitamins. I'm getting data just fine, but I'm wondering if it was possible to send that data from Angular to the C# api, so I can add the array of strings and int to a total count model.
How would I route this and what kind of data should I tell the API to expect?
The error I'm getting right now is:
Message: "No HTTP resource was found that matches the request URI 'http://localhost/api/apiFood[object Object]'."
MessageDetail: "No type was found that matches the controller named 'apiFood[object Object]'."
I've tried :
public IHttpActionResult Post([FromUri]ValueVM toEat)
{
return Ok();
}
just to see if it would route, but it didn't work out.
I'm sending the data with an ngclick="add(display)" which goes to this function in the controller:
$scope.add = function (display) {
FoodFactory.add(display).then(function (data) {
});
};
and this function in the factory:
o.add = function (display) {
var defer = $q.defer();
var config = { contentType: 'application/json' };
$http.post('api/apiFood' + display, config).success(function (data) {
defer.resolve(data);
});
return defer.promise;
};
In your model
public class toEat
{
public int id {get;set;}
public string name {get;set;}
}
In your ApiController
public class EatController : ApiController
{
[HttpPost]
public HttpResponseMessage Post(List<toEat> list)
{
return Ok();
}
}
Your request
function Request() {
$.ajax({
type: "POST",
url: url,
contentType: "application/json",
data: (your serialized array),
async: false,
success: function(data) {
console.log(data);
}
});
}