java angularjs spring file upload - html

I am trying to upload a file to a server using angularjs and Spring (to Amazon AWS).
I checked a couple of posts on uploading with the first one and the latter but I still can't get the both to work together.
File Upload using AngularJS
How to upload a file with AngularJS?
Checked also youtube for tutorials, found Black Cloud, Brent Aureli's channel and I just cannot figure it out.
You have to be authenticated in my webapp to send post requests, but I am getting errors also when I'm logged in.
Would be extremely grateful for some help.
This is my html form:
<form>
<input type="file" file-model="file">
<button ng-click="submit()" type="submit">Click</button>
</form>
Directive for the file-model:
.directive('fileModel', ['$parse', function($parse){
return {
restrict: 'A',
link: function(scope, element,attrs) {
var model = $parse(attrs.fileModel);
var modelSetter = model.assign;
element.bind('change', function() {
scope.$apply(function() {
modelSetter(scope, element[0].files[0]);
})
})
}
}
}])
Controller:
.controller('UploadController', ['$scope', 'multipartForm', function($scope, multipartForm) {
$scope.file = {};
$scope.submit = function() {
var uploadUrl = '/uploadtest';
multipartForm.post(uploadUrl, $scope.file);
}
}])
Service for multipartForm:
.service('multipartForm', ['$http', function($http){
this.post = function(uploadUrl, data) {
var fd = new FormData();
for(var key in data) {
fd.append(key, data[key]);
$http.post(uploadUrl, fd, {
transformRequest: angular.identity,
headers: {'Content-Type': undefined}
})
}
}])
Spring Endpoint:
#RestController
#RequestMapping("/storage/")
public class BucketController {
private AmazonClient amazonClient;
#Autowired
public BucketController(AmazonClient amazonClient) {
this.amazonClient = amazonClient;
}
#RequestMapping(value = "/uploadtest", method = RequestMethod.POST)
public String uploadFile(#RequestParam(value = "file") MultipartFile file) {
System.out.println("Uploading file!!!!!!!!!!!!");
return this.amazonClient.uploadFile(file);
}
}
Error that I'm getting in the browser:
angular.js:15018 Possibly unhandled rejection:
{"data":{"timestamp":1537033312586,"status":400,"error":"Bad Request","exception":"org.springframework.web.multipart.support.MissingServletRequestPartException","message":"Required request part 'file' is not present","path":"/uploadtest"},
"status":400,
"config":{"method":"POST","transformResponse":[null],
"jsonpCallbackParam":"callback",
"headers":{"Accept":"application/json,
text/plain, /",
"X-Requested-With":"XMLHttpRequest",
"Authorization":
"Basic c3p5bW9uc3R1c3pla0BnbWFpbC5jb206dGVzdA==",
"X-XSRF-TOKEN":"395d1e27-a6ee-4948-b673-39d31902e1ae"},
"url":"/uploadtest","data":{}},
"statusText":"","xhrStatus":"complete"}

The exception occurred due the missing query param 'file' which is not presented.
And in spring endpoint you should not receive a file request in Request param!
#RequestMapping(value="/uploadtest", consumes = "multipart/form-data",method = RequestMethod.POST, produces = "application/json")
public String uploadFile(MultipartHttpServletRequest request) throws Exception{
try {
MultipartFile multipartFile1 = request.getFile("file");
if (multipartFile1 != null) {
String file1 = multipartFile1.getOriginalFilename();
InputStream inputStream = multipartFile1.getInputStream();
// do whatever
}
} catch (IOException e) {
logger.error(e.getMessage());
}
return null;
}
And in Service for multipartForm change the headers content-type to : multipart/form-data
Hope this would Help!!

Related

dot net Core 3.1 API HttpRequest returns usually bad request without even sending the request

I have a strange issue with my HttpRequest, i have 2 application one is clientside and the other one is RESTAPI, the issue is i am trying to update my entity by sending a request which the content is Json
public async Task<bool> Update(string url, T obj, string id)
{
var request = new HttpRequestMessage(HttpMethod.Put, url+id);
if (obj == null || String.IsNullOrEmpty(id))
{
return false;
}
request.Content = new StringContent(JsonConvert.SerializeObject(obj),
Encoding.UTF8, "application/json");
var client = _client.CreateClient();
client.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("bearer", GetBearerToken());
HttpResponseMessage response = await client.SendAsync(request);
if (response.StatusCode == System.Net.HttpStatusCode.NoContent)
{
return true;
}
return false;
}
And here is my clientapp controller below;
[HttpPost]
public async Task<IActionResult> EditUser([FromForm] UserDTO userDTO ,string id)
{
if (!ModelState.IsValid)
{
return RedirectToAction("ErrorPage", "Error");
}
userDTO.Id = id;
await _userRepository.Update(EndPoints.UserEndPoint,userDTO,id);
return RedirectToAction("GetUsers");
}
and i dont know if it is necessary because it doesnt hit even the breakpoint but i am also showing my RESTAPI code below;
/// <summary>
/// Update user
/// </summary>
/// <param name="id"></param>
/// <param name="userDTO"></param>
/// <returns></returns>
[HttpPut("{id}")]
[Authorize(Roles = "Administrator")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<IActionResult> UpdateUser(string id, [FromBody] UserDTO userDTO)
{
var location = GetControllerActionNames();
try
{
_logger.LogInfo($"{location}: Requested an Update for id: {id} ");
if (string.IsNullOrEmpty(id) || userDTO == null || id != userDTO.Id)
{
_logger.LogError($"{location}: Request for Id: {id} is not sucessful");
return BadRequest();
}
if (!ModelState.IsValid)
{
_logger.LogWarn($"{location}: Data was incomplete!");
return BadRequest(ModelState);
}
var isExist = await _userRepo.IsExist(id);
if (!isExist)
{
_logger.LogWarn($"{location}: with Id: {id} is not exisist");
return NotFound();
}
var usermap = _mapper.Map<CompanyUser>(userDTO);
if (usermap == null)
{
_logger.LogWarn($"{location}: Data is empty");
return BadRequest();
}
var response = await _userRepo.Update(usermap);
if (!response)
{
_logger.LogError($"{location}: Update is failed ");
return NotFound();
}
_logger.LogInfo($"User is Updated");
return NoContent();
}
catch (Exception e)
{
return InternalError($"{location} - {e.Message} - {e.InnerException}");
}
}
RESTAPI code is working when i try with PostMan.
But from the client side where i send the request it sometimes works but usually gives bad request as response instanly i mean not even go to my RESTAPI. Can you help to resolve this strange problem.
I fixed the issue, on my API Login
Because i was using Microsoft Identity and when i use await PasswordEmailSignInAsync(userName, password, false, false); it automatically genereates application cookie on my API side and i used fiddler to capture requests and i saw there when i get an error or on my API side when the thread exits the application cookie also expires after that when i made a new request from my Client to My API it was giving the bad request on my client side instantly.
So i changed my signin method to var user = await _userManager.FindByEmailAsync(userDTO.Email); var result = await _userManager.CheckPasswordAsync(user, userDTO.Password);
in order to avoid from the application cookie creation. I had already JWT token structure in my application but was useless because default authorized attribute was not using bearer schema and i modified my startup.cs a little help from [Authorize Attribute not working with JWT Access Token in ASP.Net Core1
and now everything works without any problem!.
[Route("login")]
[HttpPost]
[AllowAnonymous]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
public async Task<IActionResult> Login([FromBody] UserLoginDTO userDTO)
{
var location = GetControllerActionNames();
try
{
var userName = userDTO.Email;
var password = userDTO.Password;
_logger.LogInfo($"{location}: User:{userName} - Attempted to Login");
//var result = await PasswordEmailSignInAsync(userName, password, false, false);
var user = await _userManager.FindByEmailAsync(userDTO.Email);
var result = await _userManager.CheckPasswordAsync(user, userDTO.Password);
if (result)
{
_logger.LogInfo($"{location}: User:{userName} Logged in Succesfully");
var tokenstring = await GenerateJSONWebToken(user);
return Ok(new { token = tokenstring });
}
_logger.LogWarn($"{location}: User:{userName} couldnt logged in ");
return Unauthorized(userDTO);
}
catch (Exception e)
{
return InternalError($"{location} - {e.Message} - {e.InnerException}");
}
}

POST-request with multipart/form-data from ExtJS form to .Net5 controller gets responseText empty

I have a form in ExtJS:
{
xtype: 'form',
items: [{
xtype: 'filefield',
name: 'azezFile'
}],
buttons: [{
text: 'Load',
handler: function() {
var form = this.up('form').getForm();
if(form.isValid()) {
form.submit({
url: uploadApiPath,
success: function(fp, o) {
// Never goes here
}
});
...
It sends file to a controller (.Net5):
namespace KROSS_Core.Controllers
{
[Route("api/[controller]")]
[ApiController]
[Produces("application/json")]
public class UploadController : ControllerBase
{
// POST: api/Upload
[HttpPost]
public IActionResult Post([FromForm] IFormFile file)
{
//AzezUploadFile(this.HttpContext);
return Ok(new { success = true });
//return Ok(LoadFileToBase(this.HttpContext));
//return BadRequest(new { success = false, message = "Wrong answer" });
}
Controller getting request and responses normally, but I got an exception in ext-all-debug.js:
Unhandled exception at line 6092, column 17 in
https : // localhost:44364/Website/Scripts/ext.js/ext-all-debug.js
0x800a139e - Error JavaScript: Ext.JSON.decode(): You're trying to
decode an invalid JSON String:
And response.responseText is empty in debugger. After I close that exception, the browser (IE11) asks me to save or open that json file.
Firefox shows another error in console:
"You're trying to decode an invalid JSON String: <pre>{\"success\":true}</pre>"
, but it was set [Produces("application/json")] in controller...
Google Chrome log: "You're trying to decode an invalid JSON String: <pre style="word-wrap: break-word; white-space: pre-wrap;">{"success":true}</pre>"
What is the problem and how to make it working? The same controller method loaded without sending multipart form-data goes normally and ExtJS works with response JSON.
I have no idea how to fix it in ExtJS, but I used another method of uploading a file to a server (same controller), and it works perfect:
function uploadFile(file, url, success, failure) {
var formData = new FormData();
var request = new XMLHttpRequest();
formData.append('file', file);
request.onload = function (response) {
var jsonResult = JSON.parse(response.target.responseText);
if (jsonResult.exception || jsonResult.error) {
failure(jsonResult);
}
else {
success(jsonResult);
}
};
request.open("POST", url);
request.send(formData);
}
And use it like
uploadFile(form.down('[name=fileInnputName]').extractFileInput().files[0], uploadApiPath, function() { }, function() { });

The result of json is empty when calling from cordova + angular.js

I am new to angular.js
I am trying to get json data as described in samples, as
(function () {
'use strict';
var module = angular.module('app', ['onsen']);
module.controller('GroupController', function ($scope, $http) {
$http.get("http://localhost/dinner/hOME/Categories")
.success(function (response) { $scope.categories = response; })
.error(function (data, status, headers, config) { alert(status); });
});
});
but code will go through error method with status=0, data =null
while when I open the link http://localhost/dinner/hOME/Categories in my browser there is response.
What is my mistake?
ServerSide Code (ASP.net MVC 3)
[HttpGet]
public JsonResult Categories()
{
IRecipeCategoryService rcSrv = ServiceFactory.Create<IRecipeCategoryService>();
var categoryList = rcSrv.FetchAll().Select(i => new {i.ID , i.Title }).OrderBy(j => j.Title).ToList();
return Json( categoryList
, JsonRequestBehavior.AllowGet);
}
Update (based on Sujata Chanda comments )
I have add these codes for CORS problem but it didn't help
module.config(['$httpProvider', function ($httpProvider) {
$httpProvider.defaults.useXDomain = true;
delete $httpProvider.defaults.headers.common['X-Requested-With'];
}
]);
Solution
from Christopher Marshall hint I made changes on server side based on this link
Setting Access-Control-Allow-Origin in ASP.Net MVC - simplest possible method
On server application adding this ActionFilter
public class AllowCrossSiteJsonAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
filterContext.RequestContext.HttpContext.Response.AddHeader("Access-Control-Allow-Origin", "*");
base.OnActionExecuting(filterContext);
}
}
then tagging my action as below
[AllowCrossSiteJson]
[HttpGet]
public JsonResult Categories()
{
IRecipeCategoryService rcSrv = ServiceFactory.Create<IRecipeCategoryService>();
var categoryList = rcSrv.FetchAll().Select(i => new {i.ID , i.Title }).OrderBy(j => j.Title).ToList();
return Json( categoryList
, JsonRequestBehavior.AllowGet);
}

Spring MVC Multipart Request with JSON

I want to post a file with some JSON data using Spring MVC. So I've developed a rest service as
#RequestMapping(value = "/servicegenerator/wsdl", method = RequestMethod.POST,consumes = { "multipart/mixed", "multipart/form-data" })
#ResponseBody
public String generateWSDLService(#RequestPart("meta-data") WSDLInfo wsdlInfo,#RequestPart("file") MultipartFile file) throws WSDLException, IOException,
JAXBException, ParserConfigurationException, SAXException, TransformerException {
return handleWSDL(wsdlInfo,file);
}
When I send a request from the rest client with
content-Type = multipart/form-data or multipart/mixed, I get the next exception:
org.springframework.web.multipart.support.MissingServletRequestPartException
Can anyone help me in solving this issue?
Can I use #RequestPart to send both Multipart and JSON to a server?
This is how I implemented Spring MVC Multipart Request with JSON Data.
Multipart Request with JSON Data (also called Mixed Multipart):
Based on RESTful service in Spring 4.0.2 Release, HTTP request with the first part as XML or JSON formatted data and the second part as a file can be achieved with #RequestPart. Below is the sample implementation.
Java Snippet:
Rest service in Controller will have mixed #RequestPart and MultipartFile to serve such Multipart + JSON request.
#RequestMapping(value = "/executesampleservice", method = RequestMethod.POST,
consumes = {"multipart/form-data"})
#ResponseBody
public boolean executeSampleService(
#RequestPart("properties") #Valid ConnectionProperties properties,
#RequestPart("file") #Valid #NotNull #NotBlank MultipartFile file) {
return projectService.executeSampleService(properties, file);
}
Front End (JavaScript) Snippet:
Create a FormData object.
Append the file to the FormData object using one of the below steps.
If the file has been uploaded using an input element of type "file", then append it to the FormData object.
formData.append("file", document.forms[formName].file.files[0]);
Directly append the file to the FormData object.
formData.append("file", myFile, "myfile.txt"); OR formData.append("file", myBob, "myfile.txt");
Create a blob with the stringified JSON data and append it to the FormData object. This causes the Content-type of the second part in the multipart request to be "application/json" instead of the file type.
Send the request to the server.
Request Details:
Content-Type: undefined. This causes the browser to set the Content-Type to multipart/form-data and fill the boundary correctly. Manually setting Content-Type to multipart/form-data will fail to fill in the boundary parameter of the request.
Javascript Code:
formData = new FormData();
formData.append("file", document.forms[formName].file.files[0]);
formData.append('properties', new Blob([JSON.stringify({
"name": "root",
"password": "root"
})], {
type: "application/json"
}));
Request Details:
method: "POST",
headers: {
"Content-Type": undefined
},
data: formData
Request Payload:
Accept:application/json, text/plain, */*
Content-Type:multipart/form-data; boundary=----WebKitFormBoundaryEBoJzS3HQ4PgE1QB
------WebKitFormBoundaryvijcWI2ZrZQ8xEBN
Content-Disposition: form-data; name="file"; filename="myfile.txt"
Content-Type: application/txt
------WebKitFormBoundaryvijcWI2ZrZQ8xEBN
Content-Disposition: form-data; name="properties"; filename="blob"
Content-Type: application/json
------WebKitFormBoundaryvijcWI2ZrZQ8xEBN--
This must work!
client (angular):
$scope.saveForm = function () {
var formData = new FormData();
var file = $scope.myFile;
var json = $scope.myJson;
formData.append("file", file);
formData.append("ad",JSON.stringify(json));//important: convert to JSON!
var req = {
url: '/upload',
method: 'POST',
headers: {'Content-Type': undefined},
data: formData,
transformRequest: function (data, headersGetterFunction) {
return data;
}
};
Backend-Spring Boot:
#RequestMapping(value = "/upload", method = RequestMethod.POST)
public #ResponseBody
Advertisement storeAd(#RequestPart("ad") String adString, #RequestPart("file") MultipartFile file) throws IOException {
Advertisement jsonAd = new ObjectMapper().readValue(adString, Advertisement.class);
//do whatever you want with your file and jsonAd
You can also use the next way a list List<MultipartFile> and #RequestPart("myObj") as parameters in your method inside a #RestController
#PostMapping()
#ResponseStatus(HttpStatus.CREATED)
public String create(#RequestPart("file") List<MultipartFile> files, #RequestPart("myObj") MyJsonDTOClass myObj) throws GeneralSecurityException, IOException {
// your code
}
and in the axios side with a bit of react:
const jsonStr = JSON.stringify(myJsonObj);
const blob = new Blob([jsonStr], {
type: 'application/json'
});
let formData = new FormData();
formData.append("myObj",blob );
formData.append("file", this.state.fileForm); // check your control
let url = `your url`
let method = `post`
let headers =
{
'Accept': 'application/json',
'Content-Type': 'application/json'
};
}
axios({
method,
url,
data: formData,
headers
}).then(res => {
console.log(res);
console.log(res.data);
});
We've seen in our projects that a post request with JSON and files is creating a lot of confusion between the frontend and backend developers, leading to unnecessary wastage of time.
Here's a better approach: convert file bytes array to Base64 string and send it in the JSON.
public Class UserDTO {
private String firstName;
private String lastName;
private FileDTO profilePic;
}
public class FileDTO {
private String base64;
// just base64 string is enough. If you want, send additional details
private String name;
private String type;
private String lastModified;
}
#PostMapping("/user")
public String saveUser(#RequestBody UserDTO user) {
byte[] fileBytes = Base64Utils.decodeFromString(user.getProfilePic().getBase64());
....
}
JS code to convert file to base64 string:
var reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = function () {
const userDTO = {
firstName: "John",
lastName: "Wick",
profilePic: {
base64: reader.result,
name: file.name,
lastModified: file.lastModified,
type: file.type
}
}
// post userDTO
};
reader.onerror = function (error) {
console.log('Error: ', error);
};
As documentation says:
Raised when the part of a "multipart/form-data" request identified by
its name cannot be found.
This may be because the request is not a multipart/form-data either
because the part is not present in the request, or because the web
application is not configured correctly for processing multipart
requests -- e.g. no MultipartResolver.
For Angular2+ users. Try to send JSON payload in a mixed part request as below.
formData.append("jsonPayload", new Blob([JSON.stringify(json)], {
type: "application/json"
}));
Given below complete function.
submit() {
const formData = new FormData();
formData.append('file', this.myForm.get('fileSource').value);
var json = {
"key":"value"
};
formData.append("jsonPayload", new Blob([JSON.stringify(json)], {
type: "application/json"
}));
this.http.post('http://localhost:8080/api/mixed-part-endpoint', formData)
.subscribe(res => {
console.log(res);
alert('Uploaded Successfully.');
})
}

MVC3 return JSON on error instead of HTML [duplicate]

How do I handle exceptions thrown in a controller when jquery ajax calls an action?
For example, I would like a global javascript code that gets executed on any kind of server exception during an ajax call which displays the exception message if in debug mode or just a normal error message.
On the client side, I will call a function on the ajax error.
On the server side, Do I need to write a custom actionfilter?
If the server sends some status code different than 200, the error callback is executed:
$.ajax({
url: '/foo',
success: function(result) {
alert('yeap');
},
error: function(XMLHttpRequest, textStatus, errorThrown) {
alert('oops, something bad happened');
}
});
and to register a global error handler you could use the $.ajaxSetup() method:
$.ajaxSetup({
error: function(XMLHttpRequest, textStatus, errorThrown) {
alert('oops, something bad happened');
}
});
Another way is to use JSON. So you could write a custom action filter on the server which catches exception and transforms them into JSON response:
public class MyErrorHandlerAttribute : FilterAttribute, IExceptionFilter
{
public void OnException(ExceptionContext filterContext)
{
filterContext.ExceptionHandled = true;
filterContext.Result = new JsonResult
{
Data = new { success = false, error = filterContext.Exception.ToString() },
JsonRequestBehavior = JsonRequestBehavior.AllowGet
};
}
}
and then decorate your controller action with this attribute:
[MyErrorHandler]
public ActionResult Foo(string id)
{
if (string.IsNullOrEmpty(id))
{
throw new Exception("oh no");
}
return Json(new { success = true });
}
and finally invoke it:
$.getJSON('/home/foo', { id: null }, function (result) {
if (!result.success) {
alert(result.error);
} else {
// handle the success
}
});
After googling I write a simple Exception handing based on MVC Action Filter:
public class HandleExceptionAttribute : HandleErrorAttribute
{
public override void OnException(ExceptionContext filterContext)
{
if (filterContext.HttpContext.Request.IsAjaxRequest() && filterContext.Exception != null)
{
filterContext.HttpContext.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
filterContext.Result = new JsonResult
{
JsonRequestBehavior = JsonRequestBehavior.AllowGet,
Data = new
{
filterContext.Exception.Message,
filterContext.Exception.StackTrace
}
};
filterContext.ExceptionHandled = true;
}
else
{
base.OnException(filterContext);
}
}
}
and write in global.ascx:
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleExceptionAttribute());
}
and then write this script on the layout or Master page:
<script type="text/javascript">
$(document).ajaxError(function (e, jqxhr, settings, exception) {
e.stopPropagation();
if (jqxhr != null)
alert(jqxhr.responseText);
});
</script>
Finally you should turn on custom error.
and then enjoy it :)
Unfortunately, neither of answers are good for me. Surprisingly the solution is much simpler. Return from controller:
return new HttpStatusCodeResult(HttpStatusCode.BadRequest, e.Response.ReasonPhrase);
And handle it as standard HTTP error on client as you like.
I did a quick solution because I was short of time and it worked ok. Although I think the better option is use an Exception Filter, maybe my solution can help in the case that a simple solution is needed.
I did the following. In the controller method I returned a JsonResult with a property "Success" inside the Data:
[HttpPut]
public JsonResult UpdateEmployeeConfig(EmployeConfig employeToSave)
{
if (!ModelState.IsValid)
{
return new JsonResult
{
Data = new { ErrorMessage = "Model is not valid", Success = false },
ContentEncoding = System.Text.Encoding.UTF8,
JsonRequestBehavior = JsonRequestBehavior.DenyGet
};
}
try
{
MyDbContext db = new MyDbContext();
db.Entry(employeToSave).State = EntityState.Modified;
db.SaveChanges();
DTO.EmployeConfig user = (DTO.EmployeConfig)Session["EmployeLoggin"];
if (employeToSave.Id == user.Id)
{
user.Company = employeToSave.Company;
user.Language = employeToSave.Language;
user.Money = employeToSave.Money;
user.CostCenter = employeToSave.CostCenter;
Session["EmployeLoggin"] = user;
}
}
catch (Exception ex)
{
return new JsonResult
{
Data = new { ErrorMessage = ex.Message, Success = false },
ContentEncoding = System.Text.Encoding.UTF8,
JsonRequestBehavior = JsonRequestBehavior.DenyGet
};
}
return new JsonResult() { Data = new { Success = true }, };
}
Later in the ajax call I just asked for this property to know if I had an exception:
$.ajax({
url: 'UpdateEmployeeConfig',
type: 'PUT',
data: JSON.stringify(EmployeConfig),
contentType: "application/json;charset=utf-8",
success: function (data) {
if (data.Success) {
//This is for the example. Please do something prettier for the user, :)
alert('All was really ok');
}
else {
alert('Oups.. we had errors: ' + data.ErrorMessage);
}
},
error: function (request, status, error) {
alert('oh, errors here. The call to the server is not working.')
}
});
Hope this helps. Happy code! :P
In agreement with aleho's response here's a complete example. It works like a charm and is super simple.
Controller code
[HttpGet]
public async Task<ActionResult> ChildItems()
{
var client = TranslationDataHttpClient.GetClient();
HttpResponseMessage response = await client.GetAsync("childItems);
if (response.IsSuccessStatusCode)
{
string content = response.Content.ReadAsStringAsync().Result;
List<WorkflowItem> parameters = JsonConvert.DeserializeObject<List<WorkflowItem>>(content);
return Json(content, JsonRequestBehavior.AllowGet);
}
else
{
return new HttpStatusCodeResult(response.StatusCode, response.ReasonPhrase);
}
}
}
Javascript code in the view
var url = '#Html.Raw(#Url.Action("ChildItems", "WorkflowItemModal")';
$.ajax({
type: "GET",
dataType: "json",
url: url,
contentType: "application/json; charset=utf-8",
success: function (data) {
// Do something with the returned data
},
error: function (xhr, status, error) {
// Handle the error.
}
});
Hope this helps someone else!
For handling errors from ajax calls on the client side, you assign a function to the error option of the ajax call.
To set a default globally, you can use the function described here:
http://api.jquery.com/jQuery.ajaxSetup.