Using $.ajax to POST XML to MVC Controller method - javascript

I have a simple controller function like this:
<HttpPost>
Function SaveXML(payload As String) As Boolean
If payload IsNot Nothing AndAlso payload.Length > 0 Then
Return True
Else
Return False
End If
End Function
Which I'm calling from JavaScript like this:
function SaveXML() {
var payload = '<?xml version="1.0" encoding="utf-8"?><data>XML_GOES_HERE</data>';
// Calls controller correctly but data is null
$.ajax({
url: "/Data/SaveXML/",
type: "POST",
processData: false,
contentType: "text/xml",
data: payload
})
.done(function () { alert('Application saved.'); })
.fail(function () { alert('Application failed to save.'); });
}
I'm using the example on the JQuery documentation as a base with some advice from here, here, and here. I've tried it with and without processData: false and it makes no difference.
When the call comes in to the Controller method the payload is null. If I post a simple string using some very similar code everything works fine. What precisely needs to be done in order to post XML to a Controller via $.ajax? Is it at the JavaScript or Controller end that the problem lies?

I eventually managed to find some hints on this and ended up with the following code:
$.ajax({
url: "/Data/SaveXML/",
type: "POST",
processData: false,
contentType: "application/json; charset=utf-8",
data: JSON.stringify({ payload: payload })
})
.done(function () { alert('Application saved.'); })
.fail(function () { alert('Application failed to save.'); });
The crucial differences are that the contentType is set to application/json, the data is turned into an object which is then run through the JSON.stringify method to make sure that the various characters that are unsuitable for a querystring can be sent without failing.

The default model binding doesn't work with processData set to false. If ServerXml is a string of XML, removing this should make it work:
function SendXmlToServer(ServerXml) {
$.ajax({ url: "/Home/XmlData",
type: "POST",
data: { ResXml: ServerXml }, dataType: "xml",
success: function () {
alert("Successful");
return false;
}
});
}
You'll also have to add the ValidateInput attribute to your action method, because normally "HTML markup" isn't allowed:
[HttpPost]
[ValidateInput(false)]
public ActionResult XmlData(string ResXml)
{
return null;
}
Alternatively, you could use custom model binding to seamlessly deserialize the XML, as explained in this blog post url https://lostechies.com/jimmybogard/2011/06/24/model-binding-xml-in-asp-net-mvc-3/.

I believe you may need to name the parameter you are passing to the controller.
So, something like...
var data = '<?xml version="1.0" encoding="utf-8"?><data>XML_GOES_HERE</data>';
$.ajax({
url: "/Data/SaveXML/",
type: "POST",
processData: false,
contentType: "text/xml",
data: { payload: data }
})

Related

Razor page POST handler not receiving JSON data from jQuery AJAX

I'm sending a POST request to a Razor page handler using jQuery .ajax(). The network tab shows that this data is being sent as expected:
My breakpoints confirm that I'm hitting the handler, though the invitationId is not coming over (or at the very least, not deserializing correctly):
The JavaScript is as follows:
class GenericService {
constructor(controller) {
this.controller = controller;
}
async post(data, handler = "") {
return await $.ajax({
type: "post",
beforeSend: function (xhr) {
xhr.setRequestHeader("XSRF-TOKEN", $('input:hidden[name="__RequestVerificationToken"]').val());
},
data: JSON.stringify(data),
url: `/${this.controller}${handler}`,
contentType: "application/json",
dataType: "json"
});
}
}
(async () => {
const _ajax = new GenericService("Admin/Index");
await _ajax.post({ invitationId: 1 }, "Reset");
})();
I imagine that I'm misunderstanding the implicit deserialization, but examples I've seen elsewhere on the internet seem to indicate that sending a JSON serialized object should be fine.
This is using .NET Core 3.0.
Can anyone explain what might be my issue here?
As expected, I had some wires crossed as it relates to the deserialization.
If I send the data as a plain object without serialization (and remove the corresponding json type declarations from the .ajax() options), the invitationId comes across.
return await $.ajax({
type: "post",
beforeSend: function (xhr) {
xhr.setRequestHeader("XSRF-TOKEN", $('input:hidden[name="__RequestVerificationToken"]').val());
},
data: data, //Remove JSON.stringify(...)
url: `/${this.controller}${handler}`
//contentType: "application/json", Remove
//dataType: "json" Remove
});

Web Api conroller is not called when async property is set to false in ajax query

I have a web api controller that is called by ajax query from my page. All works fine when the async value is set to true. When is set to false the ajax query does not fires. See below my code
C# web api controller
using System;
using Microsoft.Xrm.Sdk;
using CRM_WebApp.Models;
using System.Web.Http;
using System.Web.Http.Cors;
using Microsoft.Xrm.Sdk.Query;
using CRM_WebApp.Services;
using System.Text.RegularExpressions;
namespace CRM_WebApp.Controllers
{
[EnableCors(origins: "*", headers: "*", methods: "*")]
public class CallBackFormController : ApiController
{
[System.Web.Http.HttpPost]
public System.Web.Http.IHttpActionResult Post([System.Web.Http.FromBody] CallBackFormModel CallBackFormModel)
{
ConnectiontoCrm connectiontoCrm = new ConnectiontoCrm();
connectiontoCrm.GetConnectiontoCrmCopy();
//Create Lead
Entity lead = new Entity("lead");
lead["firstname"] = CallBackFormModel.FirstName;
return Json(new { result = "ok" });
}
}
}
Below is my ajax query
<script>
$("input[name='crm']").click(function(){
var Data = {FirstName : $("input[name='user_name']").val()};
makeAjaxCall(Data);
});
function makeAjaxCall(Data){
$.ajax({
url: "http://localhost:54360///api/CallBackForm",
type: "POST",
dataType: "json",
async: false,
contentType: 'application/json',
data: JSON.stringify(Data),
success: function(data){
alert("DONESUCCESS");
},
error: function(data){
alert("DONEERROR");
}
});
}
</script>
I'm not sure how can i change my code to get the error
Async:false is not a good practice. Setting async:false means you are making the process synchronous, so the browser will hang on it until it is finished -- it can't move on to your other method. Removing that option will make the call asynchronous (by default, as it should be).
if you still want to go with async:false then read the link-
http://api.jquery.com/jQuery.ajax/
It seems to be working properly, I used Fake Online REST API from github
(function CallTheServer() {
$.ajax({
url: "https://jsonplaceholder.typicode.com/posts",
type: "POST",
dataType: "json",
async: false, /* change it to true or false see the effect of alert('Check me out too'), following the ajax*/
contentType: 'application/json',
data: JSON.stringify({
title: 'foo',
body: 'bar',
userId: 1
}),
success: function(data){
alert("DONESUCCESS " + JSON.stringify(data));
},
error: function(data){
alert("DONEERROR");
}
});
alert('Check me out too');
})()
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.0/jquery.min.js"></script>

JQuery, Ajax and MVC6 parameter is null after ajax request

I'm new in asp.net core, c# and MVC 6. I'm trying to send data over ajax to my controller.
function ajaxMethodData() {
$.ajax({
url: "AjaxWithData", // hard coded for testing
type: "POST",
data: JSON.stringify({ username: "NeXT405" }),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function () {
},
error: function () {
alert('error');
}
});
}
The method in the controller looks like this. The method gets invoked by the ajax request.
[HttpPost]
public IActionResult AjaxWithData([FromBody] string username )
{
Debug.WriteLine(username);
return Json(new { success = true } );
}
It looks like the data has been sent right.
If I have understood it correctly the string should now have the value from the passed data. But it is still null.
I have also tried it with void as return value (and no dataType).
<input type="button" value="Fatty2" onclick="ajaxMethodData()" />
What I'm doing wrong?
Just change
data: JSON.stringify({ username: "NeXT405" }),
To
data: JSON.stringify("NeXT405"),
WebApi only allow to get 1 parameter from body, so the variable name is not needed for basic types.
Just check: https://www.asp.net/web-api/overview/advanced/sending-html-form-data-part-1
The last example is exactly your case

Ajax query string not being posted to ASP.NET controller

I have this Ajax function:
UpdateFIConfig: function ($appForm) {
var valid = $appForm.valid();
//if not valid the validate plugin will take care of the errors
if (valid) {
$appForm.serialize();
$.ajax({
url: '/IdentifiConfig/DefaultConfiguration/UpdateFIConfig',
data: $appForm,
dataType: 'application/json',
cache: false,
type: 'POST',
success: function (data) {
if (data.Error) {
cc.jqUtils.openDialog(data.ErrorDescription, 'Error', 'OK', null, null, null);
} else {
window.location.href = '/IdentifiConfig/DefaultConfiguration';
}
}
});
}
},
Which serializes data sent from my view into a query string. I know the data is serialized correctly because I have viewed the string with console.log($appForm), and it's correct.
However, my controller never receives the query string. I have removed a lot of code, but this is basically what the controller function looks like:
[HttpPost]
public ActionResult UpdateFIConfig(string query)
{
NameValueCollection nvc = HttpUtility.ParseQueryString(query);
System.Diagnostics.Debug.WriteLine(nvc);
}
I receive a null pointer on the line which tries to parse the query string, and I don't know why. Any help?
i have the same thing ajax in my project the only different is i don't use dataType
but contentType: "application/json; charset=utf-8"
data: "{'query' : '" + $appForm + "'}"
This bit:
$appForm.serialize();
Returns a string that you're never using. serialize won't actually modify the form. You should assign it to a variable and pass that up instead:
var data = $appForm.serialize();
$.ajax({
url: '/IdentifiConfig/DefaultConfiguration/UpdateFIConfig',
data: data,
/* etc */
});
There is probably a better way, but I get around this annoyance by accepting an Object with a string property instead of just a string. So do something like:
[HttpPost]
public ActionResult UpdateFIConfig(MyTypeWithQry query)
{ ...
and
$.ajax({ url: '/IdentifiConfig/DefaultConfiguration/UpdateFIConfig',
data: { 'query' : $appForm },
dataType: 'application/json',
...

When sending jQuery post to MVC controller getting 404 error

I'm sending from view using jQuery to MVC post action
function DoSomething(passedId) {
$.ajax({
method: "POST",
dataType: 'text',
url: '/MyController/SomeAction/',
data: { id: passedId}
}).done(function (data) {
//
});
}
And inside MyController
[HttpPost]
public ActionResult SomeAction(int id)
{
...
}
In Firebug console I'm getting 404 error.
You didn't said which version of jquery you are using. Please check jquery version and in case that this version is < 1.9.0 you should instead of
method: "POST"
use
type: "POST"
this is an alias for method, and according to jquery official documentation you should use type if you're using versions of jQuery prior to 1.9.0.
function DoSomething(passedId) {
$.ajax({
type: "POST",
dataType: 'text',
url: '/MyController/SomeAction/',
data: { id: passedId}
}).done(function (data) {
...
});
}
Tested above code and it works (each request enter inside mvc controller http post SomeAction action).
In the RFC 2616 the code 404 indicates that the server has not found anything matching the Request-URI.
So you need to look at your URL parameter.
Try the MVC conventional call using :
url: '#Url.Action("SomeAction", "MyController")',
To resolve the 404 issue:
There are a few options to resolve this. You controller/action cannot be find the way it is describe.
-If you are in a view that is in the controller for which the action your are trying to call is located, then:
url: 'SomeAction',
-If you are trying to call an action from another controller, OtherController, for example, then:
url: 'Other/SomeAction',
-To add to another answer, if you are calling your ajax inside the view (and NOT in a javascript file) then you can also use (for a controller called SomeController):
url: '#Url.Action("SomeAction", "Some")',
Additional Items Of Note:
You do not specify a content type for json (contentType indicates what you are sending):
contentType: "application/json; charset=utf-8",
I can't tell, based on your action if you are expecting 'text' or something else. However, unless expecting 'json', I would remove the data part.
You need to stringify your data
JSON.stringify(data: { id: passedId}),
In the end, I would expect it to look something like:
function DoSomething(passedId) {
var url = "SomeAction"; //if action is in OtherController then: "Other/SomeAction"
$.ajax({
method: "POST",
url: url,
data: JSON.stringify({ id: passedId}),
contentType: "application/json; charset=utf-8"
}).done(function (data) {
//
});
}
The slash at the beginning of this designates an absolute path, not a relative one.
/MyController/SomeAction/
You should include a URL or relative path.. maybe
'MyController/SomeAction/ajax.php'
or the full URL
'http://example.com/myajaxcontroller/someaction/ajax.php'
or stolen from the other guys answer
url: '#Url.Action("SomeAction", "MyController")',
To address others on here, I don't think the datatype is the
problem... OP says "I'm getting 404 error."
contentType is the type of data you're sending, so
application/json; charset=utf-8 is a common one, as is
application/x-www-form-urlencoded; charset=UTF-8, which is the
default.
dataType is what you're expecting back from the server: json, html,
text, etc. jQuery will use this to figure out how to populate the success function's parameter.
Write the code this way:
function DoSomething(passedId) {
$.ajax({
url: 'yourController/SomeAction',
type: 'POST',
data: { id: passedId},
dataType: 'json',
error: function (ex) {alert(ex.responseText)},
success: function (data)
{
if (data.Results != null) {
//use the return values
});
}
}
});
}
and the controller
public JsonResult SomeAction(int id)
{
try
{
return Json(new { Results = "Text To return or send some object or an list, etc"}, JsonRequestBehavior.AllowGet);
}
catch (Exception)
{
throw;
}
}
Finally, check that the controller has its respective view. :)
and and the library of "jQuery" updated.
just in case.
use the following ajax call
var datum = { id: passedId };
$.ajax({
url: url, // your url
type: 'POST',
data: JSON.stringify(datum),
contentType: 'application/json; charset=utf-8',
beforeSend: function () {
},
complete: function () {
},
success: function (user, status, XHR) {
},
error: function (req, status, error) {
}
});
UpDated
public ActionResult SomeAction(int id){} should accept string parameter instead of int

Categories

Resources