I have the following WebGet:
[WebGet(UriTemplate = "GetAssignments/{data}")]
[Description("GetAssignments")]
BASE.BaseResponse<object> GetAssignments(String data);
Called thusly:
var data = JSON.stringify(advancedSearchDataXml);
Helper.Service.Call({
api: 'HomeApi',
url: '?method=GetAssignments/' + data,
method: 'GET',
//data: advancedSearchDataXml,
controlId: '',
showProgress: true,
onSuccess: function (result) {
...
where data is
{"searchquery":
"<SearchQuery>
<genericsearch></genericsearch>
<region>MA</region><market>RL</market>
<recordcount>5000</recordcount>
</SearchQuery>"
}
This fails with a "EXCEPTION: The remote server returned an error: (400) Bad Request" message. What am I doing wrong?
Try removing the ?method= instead have only 'GetAssignments/'+ data .. also add a break point in your controller to make sure the right method is being hit.
Related
I have a project with areas and would like to post a view model as JSON to a controller method.
This is what I have, with performance being generated in the default area and passed to the view in area SeatSelection:
$("#addToCartButton").click(function () {
var json = #Html.Raw(Json.Encode(performance));
$.ajax({
url: 'https://#(Request.Url.Host)/SeatSelection/Home/AddToCart',
type: 'POST',
dataType: 'json',
data: json,
contentType: 'application/json; charset=utf-8',
success: function (data) {
alert(data);
}
});
});
And the action method for testing:
[System.Web.Http.Route("SeatSelection_AddToCart")]
[System.Web.Http.HttpPost]
public JsonResult AddToCart(PerformanceViewModel performance)
{
return Json(performance.Name);
}
I created the following route:
context.MapRoute(
"SeatSelection_AddToCart",
"SeatSelection/Home/AddToCart",
new { action = "AddToCart", controller = "Home", id = UrlParameter.Optional },
namespaces: new string[] { "myProject.Areas.SeatSelection.Controllers" }
);
But all I get is a internal server error 500. I also tried to use [FromBody] and setting a breakpoint to the method, but it is not invoked. I can't figure out what's wrong or missing, please help.
UPDATE
This is the json / performance:
PerformanceID=00000000-0000-0000-0000-000000000000&Name=Performance+15&StartDate=%2FDate(1360364400000)%2F&EndDate=%2FDate(1500328800000)%2F&LatestDateBookable=%2FDate(1450911600000)%2F&Organizer=Organizer+15&Location=Location+15&Availability=75&IsFull=false&IsBookable=true&HasPrice=true&BookableSeats=11&BookedSeats=94&Description=Description+of+Performance+15&Price=443
I found an error: "invalid json primitive: performanceid"
First of all, I would recommend you to use #Url.Action helper method instead of generating url like this: https://#(Request.Url.Host)/SeatSelection/Home/AddToCart.
Secondly, always validate params which comes from the browser. return Json(performance.Name) looks suspicious. What is performance will be null? This might be a problem of your internal server error 500.
If this is not a problem then try to send string instead of JSON to the server and validate and parse JSON on the server side.
You can use Url.Action method like this. I suppose SeatSelection is an area in your project.
$.ajax({
url: '#Url.Action("AddToCart", "Home", new { Area = "SeatSelection"})',
I have the following scenario: I have a kendo.dataSource which is populated via read request to a WebApi Controller. In addition to the read, I am sending a couple of parameters, which then I use in my controller to do some server logic. I was able to send as many simple parameters as I want via the parameterMap property of the transport function. Till now it was a simple get request. However now I need to send additional json object to the controller as a parameter. I read that I have to transform the Get request to Post and put the Json onto the body of the request but I don't know how to do it.
The code that I have so far:
var gridDataSource = new kendo.data.DataSource({
type: 'odata-v4',
transport: {
read: {
url: wave.alarmsAndEvents.api('api/alarmsAndEventsSearch/post'),
type: "POST",
data: {
SearchModel: JSON.stringify(vm.searchModel)
},
contentType: 'application/json; charset=utf-8',
},
parameterMap: function (data, operation) {
if (operation === "read") {
data.startDate = kendo.toString(vm.selectedTimeInterval.start, "G");
data.endDate = kendo.toString(vm.selectedTimeInterval.end, "G");
data.alarmsToDisplay = vm.maxRecords;
}
return kendo.stringify(data);
}
},
pageSize: vm.maxRecords,
error: function (e) {
alert(e.xhr.responseText);
}
});
The SearchModel is the thing that I want to send as JSon. The rest are simple DateTime and int parameters.
My controller:
[HttpPost]
public IQueryable<AlarmsSearchViewModel> Post(DateTime startDate, DateTime endDate, int alarmsToDisplay, [FromBody]JToken jsonbody)
{
....
return something;
}
I end up with Not Found 404, but I am pretty sure that I have messed up the parameters. And from the Network window I can see that the json object is not sent at all. Any help will be much appreciated!
I have a "test.ini" file in my server, contain the following text:
"[ALL_OFF]
[ALL_ON]
"
I'm trying to get this file content via $http service, here is part of my function:
var params = { url: 'test.ini'};
$http(params).then(
function (APIResponse)
{
deferred.resolve(APIResponse.data);
},
function (APIResponse)
{
deferred.reject(APIResponse);
});
This operation got an Angular exception (SyntaxError: Unexpected token A).
I opened the Angular framework file, and I found the exeption:
Because the text file content start with "[" and end with "]", Angular "think" that is a JSON file.
Here is the Angular code (line 7474 in 1.2.23 version):
var defaults = this.defaults = {
// transform incoming response data
transformResponse: [function(data) {
if (isString(data)) {
// strip json vulnerability protection prefix
data = data.replace(PROTECTION_PREFIX, '');
if (JSON_START.test(data) && JSON_END.test(data))
data = fromJson(data);
}
return data;
}],
My question:
How can I force angular to not make this check (if (JSON_START.test(data) && JSON_END.test(data))) and not parse the text response to JSON?
You can override the defaults by this:
$http({
url: '...',
method: 'GET',
transformResponse: [function (data) {
// Do whatever you want!
return data;
}]
});
The function above replaces the default function you have posted for this HTTP request.
Or read this where they wrote "Overriding the Default Transformations Per Request".
You can also force angular to treat the response as plain text and not JSON:
$http({
url: '...',
method: 'GET',
responseType: 'text'
});
This will make sure that Angular doesn't try to auto detect the content type.
I'm new to JSON and have been using it with MVC3 ASP.NET but could somebody shed some light on how to return an error per a JSON result?
I have the following call from my View:
$.ajax({
type: "POST",
dataType: "json",
url: "EditJSON",
data: { FilmID: InputFilmID, Title: InputTitle, Description: InputDescription},
success: function (result) {
alert(result.Message + " updating film " + result.Title);
window.location = "../All";
},
error: function (error) {
alert('error');
}
});
Controller handles the request as a success. What would I pass back for a JSON error so that the error: function handled back at the View?
[AcceptVerbs("POST")]
public JsonResult EditJSON(BobsMoviesMVC2.Models.Film film)
{
filmRepository.Update(film);
return Json(new {Message = "Success", Title = film.Title });
// What would I return for an error here?
}
Thanks!
jQuery uses the HTTP response code to determine success or failure.
HTTP response codes >= 400 are considered errors. HTTP response codes >= 200 and < 400 are considered successes.
Return appropriate HTTP codes from your server-side code to get the behavior you're after.
Confirmed, in .NET you can put:
Response.StatusCode = (int)HttpStatusCode.InternalServerError,
or whatever error status code you wish, right before your JSON return statement. (Thank you Mariah).
Check out the 'error' option of the jquery ajax call to see what you can do with the resulting error on the client-side.
A header with a status code other than 2xx or 3xx, probably a 5xx or 4xx error code.
I have a javascript client that is going to send json-formatted data to a set of MVC2 controllers. The client will format the json, and the controller will have no prior knowledge of how to interpret the json into any model. So, I can't cast the Controller method parameter into a known model type, I just want to grab the generic json and pass it to a factory of some sort.
My ajax call:
function SendObjectAsJSONToServer(object,url,idForResponseHTML) {
// Make a call to the server to process the object
var jsonifiedObject = JSON.stringify(object);
$.ajax({
url: url // set by caller
, dataType: 'json'
, data: jsonifiedObject
, type: 'GET'
, error: function(data) { alert('error in sendObjectAsJSONToServer:' + data); }
, success: function(data) {
alert(data.message); // Note that data is already parsed into an object
}
});
}
My MVC Controller:
public ActionResult SaveForm(string obj)
{
// Ok, try saving the object
string rc = PassJSONToSomething(obj.ToString());
string message = "{\"message\":\""+rc+"\",\"foo\":\"bar\"}";
return new ContentResult { Content = message, ContentType = "application/json" };
}
The problem is that obj is always null. Can anyone tell me how I should structure the ajax call and the controller parameter so that I get my json to the server? I'm using MVC2. This may appear to be a duplicate of some SO questions, but in my case I do not know the Model that the json maps to, so I can't use a specific model type in the controller parameter type.
Thanks very much.
Have you tried something like that?
$.ajax({
url: url // set by caller
, dataType: 'json'
, data: {obj :jsonifiedObject}
, contentType: 'application/json; charset=utf-8'
, type: 'GET'
, error: function(data) { alert('error in sendObjectAsJSONToServer:' + data); }
, success: function(data) {
alert(data.message); // Note that data is already parsed into an object
}
});