Send FormData using Jquery-Ajax to C# Web-Api - c#

I have the following function:
public class UserRequest
{
public string RequestMessage { get; set; }
public HttpPostedFileBase Photo { get; set; }
}
public void CreateRequest(UserRequest userRequest)
{
}
When I post to this function with the following script the posted image is always null:
var requestMessage = document.getElementById("txtReqMessage").value;
var inputFile = document.getElementById("reqphoto");
var imageFile = inputFile.files[0];
$.ajax({
type: "POST",
url: "/UserRequest/CreateRequest/",
contentType: 'application/json; charset=utf-8',
data: JSON.stringify({
"RequestMessage": requestMessage,
"Photo": imageFile
}),
success: function () {
alert("Success");
}
I read about posting complex data so I changed the script to:
var requestMessage = document.getElementById("txtReqMessage").value;
var inputFile = document.getElementById("reqphoto");
var imageFile = inputFile.files[0];
var formData = new FormData();
formData.append("RequestMessage", requestMessage);
formData.append("Photo", imageFile);
$.ajax({
type: "POST",
url: "/UserRequest/CreateRequest/",
data: formData,
dataType: 'json',
contentType: false,
processData: false,
success: function () {
alert("Success");
}
});
But now something is wrong I get Error 500.

I changed it to this:
public void CreateRequest()
{
var httpRequest = HttpContext.Current.Request;
var userRequest = new UserRequest
{
RequestMessage = httpRequest.Form["RequestMessage"],
Photo = httpRequest.Files["RequestPhoto"],
};
}
var formData = new FormData();
formData.append("RequestMessage", requestMessage);
formData.append("RequestPhoto", imageFile);
$.ajax({
type: "POST",
url: "/UserRequest/CreateRequest",
data: formData,
processData: false,
success: function () {
alert("OK");
},
error: function () {
alert("Error");
}
});

define the method as web method
[WebMethod]
public void CreateRequest(UserRequest userRequest)
{
}

you should read data in a FormDataCollection
public void CreateRequest(FormDataCollection form)
{
}
try changing contentType ajax property to
contentType: 'multipart/form-data'
you are using false value that should be used only when you are sending files

Related

Ajax call is not passing parameter to controller method

In the Controller I added a method to perform some live data exchange into a div.
public class TextItemsController : Controller
{
//[HttpPost]
public JsonResult SpinText(string Body)
{
SpinningResult spinningResult = new SpinningResult();
spinningResult.Spintext = "This is the result text";
string jsonResult = JsonConvert.SerializeObject(spinningResult);
return Json(jsonResult);
}
}
This works in general and the result is sent back to the calling Ajax method and the div is updated with the result text as intended. So the general communication seems to work. But I never receive the input string from the Ajax call.
function doSpinning() {
//var token = $('input[name="__RequestVerificationToken"]', $('#textForm')).val();
var myData = { Body : "Hello" };
//var dataWithAntiforgeryToken = $.extend(myData, { '__RequestVerificationToken': token });
var requestData = JSON.stringify(myData);
$.ajax({
url: "/TextItems/SpinText",
type: "POST",
dataType: "json",
contentType: "application/json; charset=utf-8",
data: requestData,
success: function (data) {
var json = JSON.parse(data);
document.getElementById("PreviewText").innerHTML = json["Spintext"];
},
error: function () {
document.getElementById("PreviewText").innerHTML = "Error";
}
});
}
$("#spinButton").on('click', doSpinning);
data seems to have the correct value "{"Body":"Hello"}" before the post but string Body is always null.
Can you try to prefix your parameter with [FromBody] like this :
public JsonResult SpinText([FromBody] DtoBody Body)
And use a data transfer object so the JsonSerializer will know how to map the sent data
public class DtoBody
{
public string Body {get;set;}
}
You are posting an object with a Body property, and your method expects a string value. These don't match up, obviously, but you don't need to post an object when you only want to pass in a primitive:
$.ajax({
url: "/TextItems/SpinText",
type: "POST",
dataType: "json",
contentType: "application/json; charset=utf-8",
data: "Hello",
success: function (data) {
var json = JSON.parse(data);
document.getElementById("PreviewText").innerHTML = json["Spintext"];
},
error: function () {
document.getElementById("PreviewText").innerHTML = "Error";
}
});
Note that this is not your only problem though, as you are doing a double JSON serialization on your Action:
// serialize to JSON
string jsonResult = JsonConvert.SerializeObject(spinningResult);
//serialize the serialized object
return Json(jsonResult);
You never have to explicitly serialize to JSON, that's what the helper does for you.
Just use:
public IActionResult SpinText(string Body)
{
SpinningResult spinningResult = new SpinningResult();
spinningResult.Spintext = "This is the result text";
return Json(spinningResult);
}
And, again, you don't need to double-parse the JSON on the AJAX result:
success: function (data) {
document.getElementById("PreviewText").innerHTML = data.spintext;
},
Thanks a lot, I got it with a mix of your help.
DTO
public class SpinningInput
{
public string Title { get; set; }
public string Body { get; set; }
public string Tags { get; set; }
public string Keyword { get; set; }
}
Controller
public JsonResult SpinText([FromBody]SpinningInput spinningInput)
{
SpinningResult spinningResult = new SpinningResult();
spinningResult = Utility.Spinning.SpinText(spinningInput);
return Json(spinningResult);
}
Javascript
function doSpinning() {
const textBody = document.getElementById("Body").value;
const textTitle = document.getElementById("Title").value;
const textTags = document.getElementById("Tags").value;
const textKeyword = document.getElementById("Keyword").value;
var textData = { Title: textTitle, Body: textBody, Tags: textTags, Keyword: textKeyword };
var requestData = JSON.stringify(textData);
$.ajax({
url: "/TextItems/SpinText",
type: "POST",
dataType: "json",
contentType: "application/json; charset=utf-8",
data: requestData,
success: function (data) {
document.getElementById("PreviewText").innerHTML = data.spintext;
document.getElementById("WordCount").innerHTML = data.wordCount;
document.getElementById("KeywordDensity").innerHTML = data.keywordDensity + "%";
},
error: function () {
document.getElementById("PreviewText").innerHTML = "Error";
}
});
}
$("#spinButton").on('click', doSpinning);

Passing json to mvc controller

I am trying to post some data via jQuery ajax to an Asp.Net MVC controller. I have the follow class which I am working with:
public class InnerStyle
{
[JsonProperty("color")]
public string HeaderColor { get; set; }
[JsonProperty("font-size")]
public string HeaderFontSize { get; set; }
[JsonProperty("font-family")]
public string HeaderFontFamily { get; set; }
}
The post method looks like:
public JsonResult UpdateRecord(InnerStyle innerStyle)
{
//Do some validation
return Json("OK");
}
And my jQuery looks like:
$('#font-size-ddl').change(function () {
var value = $(this).val();
headerObj["font-size"] = value;
console.log(JSON.stringify({ innerStyle: headerObj }));
$.ajax({
type: "POST",
url: "#Url.Action("UpdateRecord", "Document")",
data: JSON.stringify({ innerStyle: headerObj}),
contentType: "application/json; charset=utf-8",
success: function (data) {
console.log(data);
}
});
});
The console.log in the above change event produces the following JSON string:
{"innerStyle":{"text-align":"","font-size":"20px","color":""}}
Now the issue I am having is if I set a break point on my UpdateRecord Action and see what is coming through the innerStyle object is null. Can someone tell me where I am going wrong please.
I tried using the below code and it's working fine.
$.ajax({
type: "POST",
url: "#Url.Action("UpdateRecord", "Document")",
data: JSON.stringify({"text-align":"","font-size":"20px","color":""}),
contentType: "application/json; charset=utf-8",
success: function (data) {
console.log(data);
}
});
I simply removed the parameter name "innerStyle". I just noticed one thing which might be a typo error. You are passing a property "text-align":"" instead of "font-family". So it's not populating all properties inside the controller's action UpdateRecord(InnerStyle innerStyle). You should pass similar to the below json object to map the entire object on controller's action UpdateRecord(InnerStyle innerStyle)
{
"color": "sample string 1",
"font-size": "sample string 2",
"font-family": "sample string 3"
}
#Code, your code is fine. It's just you cannot use [Json Property] while you are hitting controller via ajax. you have to use real class properties.
$('#font-size-ddl').change(function () {
var value = $(this).val();
var headerObj = {};
headerObj["HeaderColor"] = "Red";
headerObj["HeaderFontSize"] = value;
headerObj["HeaderFontFamily"] = "Arial";
console.log(JSON.stringify({ custom: headerObj }));
$.ajax({
type: "POST",
url: "#Url.Action("UpdateRecord", "Employee")",
traditional: true,
data: JSON.stringify({ custom: headerObj }),
dataType: JSON,
contentType: "application/json; charset=utf-8",
success: function (data) {
console.log(data);
}
});
});

Passing JSON Object from Javascript to ASP.Net

I am trying to pass the Json string sObject from javascript to c#. In c# I am trying to load data from this JSon string to a Object.
I get a Bad Request error in Javascript.
C# Entity Object:
public class StatusEntity
{
public string WorkOrderID { get; set; }
public string JobID { get; set; }
public string ClientID { get; set; }
}
c# WCF Service:
[WebInvoke(UriTemplate = "/updatestatus", Method = "POST", BodyStyle = WebMessageBodyStyle.WrappedRequest, ResponseFormat = WebMessageFormat.Json)]
public string updateStatus(List<StatusEntity> _objStatus)
{
string sResult = string.Empty;
try
{
// SOME CODE HERE
}
catch (Exception)
{
sResult = string.Empty;
throw;
}
finally
{
}
return sResult;
}
Javascript Code:
function updateStatus() {
var sObject = '[{"WorkOrderID":"9","JobID":"48","ClientID":"9"},{"WorkOrderID":"9","JobID":"48","ClientID":"10"}]';
$.ajax({
cache: false,
type: "POST",
async: false,
url: "../JobMatchingService/updatestatus",
contentType: "application/json; charset=utf-8",
dataType: "json",
// OLD CODE - NOT WORKING
data: sObject,
// NEW CODE CHANGES WORKING
data: '{"_objStatus":' + _objStatus + '}',
success: function (response) {
alert(response);
},
error: function (xhr, options, error) {
alert(error);
}
});
}
Change _objStatus to a string in the method parameter, then use a try/catch to transform it into a StatusEntity like so:
var status = JsonConvert.DeserializeObject<List<StatusEntity>>(jsonString);
Made changes to the javascript, the data has to specified as below:
// OLD CODE - NOT WORKING
data: sObject,
// NEW CODE CHANGES WORKING
data: '{"_objStatus":' + _objStatus + '}',
function updateStatus() {
var sObject = '[{"WorkOrderID":"9","JobID":"48","ClientID":"9"},{"WorkOrderID":"9","JobID":"48","ClientID":"10"}]';
$.ajax({
cache: false,
type: "POST",
async: false,
url: "../JobMatchingService/updatestatus",
contentType: "application/json; charset=utf-8",
dataType: "json",
// OLD CODE - NOT WORKING
data: sObject,
// NEW CODE CHANGES WORKING
data: '{"_objStatus":' + _objStatus + '}',
success: function (response) {
alert(response);
},
error: function (xhr, options, error) {
alert(error);
}
});
}

Return ViewModel Data to Javascript function MVC 4?

I am trying to pass the data of the view model to one js method and from there I need to pass the VM to another controller method to show the data.
here is what I have did:
$(document).ready(function () {
var content = GetHomeContent('/Home/CastContent');
if (content) {
saveBDContent('/Message/Details/', content);
}
});
function GetHomeContent(url) {
var modelData;
$.ajax({
url: url,
cache: false,
async: false,
type: "GET",
contentType: 'application/json',
success: function (data) {
if (data) {
modelData = data;
}
},
error: function (data) {
status = false;
}
})
return modelData;
};
function saveBDContent(url, data) {
var status = false;
$.ajax({
url: url,
cache: false,
async: false,
type: "GET",
data: JSON.stringify(data),
contentType: 'application/json',
success: function (data) {
if (data == "200") {
status = true;
}
},
error: function (data) {
status = false;
}
})
return status;
};
The problem am facing is , the content I retrived from the method show the namespace of the ViewModel. When I pass that to the new controlled the Viewmodel content is coming null.
Do I need to add anything to get/Pass the proper content ?
The Dummy method skeleton
public ActionResult CastContent()
{
CastVM broadcastVM = new CastVM();
return Json( broadcastVM);
}
I have missed out the JsonRequestBehavior.AllowGet in my controller method, I have added and the results are coming perfectly.
public ActionResult CastContent()
{
CastVM broadcastVM = new CastVM();
return Json( broadcastVM,JsonRequestBehavior.AllowGet);
}
and also I have set the HTTP status as post in the jquery method
Do something like that in the Controller:
public JsonResult QuickSave(BookEntry bookEntry) {
YourViewModel model = new YourViewModel();
return Json(model);
}
EDIT >> The associated Javascript code is :
$.ajax({
type: "POST",
url: 'The URL',
data: 'The JSON data',
dataType: "json",
success: function (theViewModel) {
// Do some JS stuff with your model
},
error: function (xhr, status, error) {
// Do some error stuff
}
});

Pass array by ajax with MVC 4

I'm having problems to passa an Javascript array by ajax to my application. The ajax call is executing my server-side method but the parameter is null, and, even before my method finish processing, ajax throws error (execute its error function).
This is my ajax call:
<script>
var permissoesUsuario = Array();
$(function () {
//funcao de envio das permissoes
$('#btnSalvar').click(function () {
//desabilita o botao de salvar
$(this).attr('disabled', 'disabled');
$.each($('input[name="chkPermissao"]:checked'), function () {
permissoesUsuario.push({
IdEmpresa: $(this).attr('data-empresa'),
IdPermissao: $(this).attr('data-permissao')
});
});
$.ajax({
url: '#(Url.Content("~/Funcionario/Permissoes"))',
data: JSON.stringify(permissoesUsuario),
type: 'POST',
contentType: 'application/json; charset=utf-8',
success: function (response) {
permissoesUsuario = Array();
if (response == '') {
window.location = '#(Url.Content("~/Funcionario"))';
}
},
error: function(){
console.log('Erro');
}
});
});
</script>
And my server-side method:
[HttpPost]
public ActionResult Permissoes(IList<PermissaoAcessoInputModel> permInput)
{
//Do something
}
My permInput variable is null..
This is my PermissaoAcessoInputModel Class:
public class PermissaoAcessoInputModel
{
public virtual int IdPermissao { get; set; }
public virtual ulong? IdEmpresa { get; set; }
}
Have you tried setting
traditional: true
In your AJAX options?
ex
$.ajax({
url: '#Url.Content("~/Funcionario/Permissoes")',
data: JSON.stringify(permissoesUsuario),
type: 'POST',
traditional: true,
contentType: 'application/json; charset=utf-8',
success: function (response) {
permissoesUsuario = Array();
if (response == '') {
window.location = '#Url.Content("~/Funcionario")';
}
},
error: function(){
console.log('Erro');
}
});

Categories

Resources