How to pass two objects to web api? - asp.net

Here is my WebAPI POST method which expects BookingDetail and BookingVenue objects:
[HttpPost]
[ValidateUserSession]
public JsonResult CheckBooking(BookingDetail BookingDetail, BookingVenue objBV)
{
try
{
if (BookingDetail != null && objBV != null)
{
bool result = Ibook.checkBookingAvailability(BookingDetail, objBV);
if (result == false)
{
return Json("NotAvailable");
}
else
{
return Json("Available");
}
}
else
{
return Json("Available");
}
}
}
Angular code from where I'm getting the values from UI and making a post passing these 2 objects:
this.checkbookingavailability = function (Book) {
var BookingVenueObj = {
EventTypeID: Book.EventSelected,
VenueID: Book.Venueselected,
GuestCount: Book.NoofGuest,
};
var BookingDetailObj = {
BookingDate: Book.BookingDate
};
var response =
$http({
method: "POST",
url: "/Booking/CheckBooking/",
headers: {
'RequestVerificationToken': $cookies.get('EventChannel')
},
data: { BookingDetail: BookingDetailObj, BookingVenue: BookingVenueObj }
});
return response;
}
Problem is in my WebAPI code, both the objects as null

You can only pass one object in the body so I would recommend you to create a new DTO "BookingDto" for that containing BookingDetail and BookingVenue as member and change the signature of your WebAPI to this:
[HttpPost]
[ValidateUserSession]
public JsonResult CheckBooking([FromBody]BookingDto bookingObj)

You need to serialize JSON object which you are sending to server just by calling JSON.stringify over object.
var response =
$http({
method: "POST",
url: "/Booking/CheckBooking/",
headers: {
'RequestVerificationToken': $cookies.get('EventChannel')
},
data: JSON.stringify({
BookingDetail: BookingDetailObj,
BookingVenue: BookingVenueObj
})
});
return response;

As dear Pankaj mentioned you need to Serialize your data objects with Stringify function in javascript, Also consider that you must mention that this http request contain Application/JSON content. All these can be shown here:
var response =
$http({
method: "POST",
url: "/Booking/CheckBooking/",
headers: {
'RequestVerificationToken': $cookies.get('EventChannel'),
'Content-Type' : 'application/json'
},
data: JSON.stringify({
BookingDetail: BookingDetailObj,
BookingVenue: BookingVenueObj
})
});
return response;

Related

How to post multipart/formdata using fetch in react-native?

i want to post Form Data like that.
what should i prepare for sending image file data?
i have Uri, type, filename, size.
then will use fetch for it.
Content-type in header is 'multipart/formdata'
thanks for helping
You should have an upload function, which should look like this:
upload(url, data) {
let options = {
headers: {
'Content-Type': 'multipart/form-data'
},
method: 'POST'
};
options.body = new FormData();
for (let key in data) {
options.body.append(key, data[key]);
}
return fetch(requestUrl, options)
.then(response => {
return response.json()
.then(responseJson => {
//You put some checks here
return responseJson;
});
});
}
And you call it this way, sending the image blob path:
this.upload('http://exampleurl.com/someApiCall', {
file: {
uri: image.path,
type: image.mime,
name: image.name,
}
}).then(r => {
//do something with `r`
});
You need to create an instance of FormData and pass that as the body to fetch, like so:
const data = new FormData()
data.append("something", something)
fetch(url, { method: 'POST', body: form })
React Native code
fetch("url" ,{
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
method:'POST',
body: JSON.stringify(this.state.imageholder)
}).catch(function(error) {
console.log('There has been a problem with your fetch operation: ' + error.message);
throw error;
});
Spring boot code
#PostMapping(value="/",consumes = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<?> saveCustomerOrder(#RequestBody String[] file) throws SerialException, SQLException {
TestImg imgObj=null;
for (String img : file) {
imgObj=new TestImg();
byte[] decodedByte = Base64.getDecoder().decode(img);
Blob b = new SerialBlob(decodedByte);
imgObj.setImg(b);
testRepo.save(imgObj);
}

ASP.Net MVC Get ID of newly added record from AJAX post

How do I retrieve the ID from the following model, after the following JQuery/Ajax posts to it:
JQuery:
$.ajax({
type: 'POST',
url: '/api/searchapi/Post',
contentType: 'application/json; charset=utf-8',
data: toSend,
}).done(function (msg) {
alert( "Data Saved: " + msg );
});
Controller:
// POST api/searchapi
public Void Post(Booking booking)
{
if (ModelState.IsValid)
{
tblCustomerBooking cust = new tblCustomerBooking();
cust.customer_email = booking.Email;
cust.customer_name = booking.Name;
cust.customer_tel = booking.Tel;
bc.tblCustomerBookings.Add(cust);
bc.SaveChanges();
long ID = cust.customer_id;
Return ID; <-- what do I enter here?
}
Return "Error"; <-- and here?
}
How can I get the ID back into the jQuery script, and if the model isn't valid, how do I return an error to the jQuery?
Thanks for any help,
Mark
You could return a JsonResult
[HttpPost]
public ActionResult Post(Booking booking)
{
if (ModelState.IsValid)
{
tblCustomerBooking cust = new tblCustomerBooking();
cust.customer_email = booking.Email;
cust.customer_name = booking.Name;
cust.customer_tel = booking.Tel;
bc.tblCustomerBookings.Add(cust);
bc.SaveChanges();
return Json(new { id = cust.customer_id });
}
return HttpNotFound();
}
and then on the client simply:
$.ajax({
type: 'POST',
url: '/api/searchapi/Post',
contentType: 'application/json; charset=utf-8',
data: toSend,
}).done(function (msg) {
alert('Customer id: ' + msg.id);
}).error(function(){
// do something if the request failed
});
One way to do it is like this:
In your controller:
public Void Post(Booking booking)
{
//if valid
return Json(new {Success = true, Id = 5}); //5 as an example
// if there's an error
return Json(new {Success = false, Message = "your error message"}); //5 as an example
}
In your ajax post:
$.ajax({
type: 'POST',
url: '/api/searchapi/Post',
contentType: 'application/json; charset=utf-8',
data: toSend,
success: function(result) {
if (result.Success) {
alert(result.Id);
}
else {
alert(result.Message);
}
}
});
returning void isn't a good idea, use JsonResult
Because you are using JavaScript, I recommend using JSON.
return this.Json(new { customerId = cust.customer_id});
In order to receive a return value, the controller method must return something other than void.
Does your controller compile? Your post method has a void return type, so it should fail compilation when it sees the return ID and return "Error" commands

Web Api Parameter always null

Why is the parameter always null when I call the below Post method with the below ajax?
public IEnumerable<string> Post([FromBody]string value)
{
return new string[] { "value1", "value2", value };
}
Here is the call to the Web API method via ajax:
function SearchText() {
$("#txtSearch").autocomplete({
source: function (request, response) {
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: "api/search/",
data: "test",
dataType: "text",
success: function (data) {
response(data.d);
},
error: function (result) {
alert("Error");
}
});
}
});
}
$.ajax({
url: '/api/search',
type: 'POST',
contentType: 'application/x-www-form-urlencoded; charset=utf-8',
data: '=' + encodeURIComponent(request.term),
success: function (data) {
response(data.d);
},
error: function (result) {
alert('Error');
}
});
Basically you can have only one parameter of scalar type which is decorated with the [FromBody] attribute and your request needs to use application/x-www-form-urlencoded and the POST payload should look like this:
=somevalue
Notice that contrary to standard protocols the parameter name is missing. You are sending only the value.
You can read more about how model binding in the Web Api works in this article.
But of course this hacking around is a sick thing. You should use a view model:
public class MyViewModel
{
public string Value { get; set; }
}
and then get rid of the [FromBody] attribute:
public IEnumerable<string> Post(MyViewModel model)
{
return new string[] { "value1", "value2", model.Value };
}
and then use a JSON request:
$.ajax({
url: '/api/search',
type: 'POST',
contentType: 'application/json; charset=utf-8',
data: JSON.stringify({ value: request.term }),
success: function (data) {
response(data.d);
},
error: function (result) {
alert('Error');
}
});
You cannot use a simple type for the [FromBody] attribute with the JSON content type. Although the default in Visual Studio has a string from body this is for the application/x-www-form-urlencoded content type.
Put the string value as a property on a basic model class and the deserialiser will work.
public class SimpleModel()
{
public string Value {get;set;}
}
public IEnumerable<string> Post([FromBody]SimpleModel model)
{
return new string[] { "value1", "value2", model.Value };
}
Change the JSON you are sending to:
{"Value":"test"}
whenever we are calling web api action and which take [frombody] parameter then input parameter prefix with =
for example
public string GetActiveEvents([FromBody] string XMLRequestString) {
}
to call above web api action
URI
2.
User-Agent: Fiddler
Content-Type: application/x-www-form-urlencoded
Host: localhost:54702
Content-Length: 936
request body is =data
I hope this will give clear idea.
I've just had a beast of a time with this and .NET Core Web API. So hopefully to save time for someone: The actual problem for me was simple - I wasn't converting to the correct type (Notice #Darins answer uses a VM rather than a string).
The default type in the template is string. I thought because we're sending stringified JSON, we would see a JSON string, but this was not the case. I had to make it the correct type.
E.g. This failed
[EnableCors("AllowAll")]
[HttpPost]
public HttpResponseMessage Post([FromBody]string value)
{
// Do something with the blog here....
var msg = new HttpResponseMessage(System.Net.HttpStatusCode.OK);
return msg;
}
But this worked.
[EnableCors("AllowAll")]
[HttpPost]
public HttpResponseMessage Post([FromBody]Blog value)
{
// Do something with the blog here....
var msg = new HttpResponseMessage(System.Net.HttpStatusCode.OK);
return msg;
}
Ajax Call
function HandleClick() {
// Warning - ID's should be hidden in a real application
// - or have covering GUIDs.
var entityData = {
"blogId": 2,
"url": "http://myblog.com/blog1",
"posts": [
{
"postId": 3,
"title": "Post 1-1",
"content": "This is post 1 for blog 1",
"blogId": 2
},
{
"postId": 4,
"title": "Post 1-2",
"content": "This is post 2 for blog 1",
"blogId": 2
}
]
};
$.ajax({
type: "POST",
url: "http://localhost:64633/api/blogs",
async: true,
cache: false,
crossDomain: true,
data: JSON.stringify(entityData),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (responseData, textStatus, jqXHR) {
var value = responseData;
},
error: function (responseData, textStatus, errorThrown) {
alert('POST failed.');
}
});
}

Getting ContentType in ASP.NET MVC 3

i have the following code in c#. I'm using ASP.NET MVC 3.
public override void ExecuteResult(ControllerContext context)
{
// If ContentType is not expected to be application/json, then return XML
if ((context.HttpContext.Request.ContentType ?? String.Empty).Contains("application/json"))
{
new JsonResult { Data = this.Data }
.ExecuteResult(context);
}
else
{
using (MemoryStream stream = new MemoryStream(500))
{
using (var xmlWriter = XmlTextWriter.Create(
stream,
new XmlWriterSettings()
{
OmitXmlDeclaration = true,
Encoding = UTF8,
Indent = true
}))
{
new XmlSerializer(typeof(T), IncludedTypes)
.Serialize(xmlWriter, this.Data);
}
// NOTE: We need to cache XmlSerializer for specific type. Probably use the
// GenerateSerializer to generate compiled custom made serializer for specific
// types and then cache the reference
new ContentResult
{
ContentType = "text/xml",
Content = UTF8.GetString(stream.ToArray()),
ContentEncoding = UTF8
}
.ExecuteResult(context);
}
}
}
I'm trying to return a json or a xml result depending the request. The problem is that i get context.HttpContext.Request.ContentType = "" when i run it.
Is there a way to make the application know that the request is "application/json"?
I'm returning this result object in a controller method called GetGoogleMapsMarkers:
$(document).ready(function () {
$.ajax({
type: "POST",
url: "http://localhost:1939/API/Google/GetGoogleMapsMarkers",
datatype: "json",
contentType: "application/json; charset=utf-8",
success: function (data) {
alert(data);
}
}
});
Help me please.
Thanks.
Unable to reproduce. Here's what I tried:
Result:
public class TestResult : ActionResult
{
public override void ExecuteResult(ControllerContext context)
{
var ct = context.HttpContext.Request.ContentType;
context.HttpContext.Response.Write(ct);
}
}
Controller:
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
public ActionResult Foo()
{
return new TestResult();
}
}
View:
<script type="text/javascript">
$.ajax({
url: '#Url.Action("foo")',
type: 'POST',
contentType: 'application/json; charset=utf-8',
success: function (result) {
alert(result);
}
});
</script>
The AJAX call resulted in the correct request content type to be fetched.
i added
data: { },
to the ajax call and it worked.... it's weird but it made it work...

Asp.net Mvc Ajax Json (post Array)

javascript\jQuery:
var items = new Array();
var obj { Begin: "444", End: "end" };
items.push(obj);
items.push(obj);
var request = {
DateStart: $("#DateStart").val(),
mass: items
};
$.post("/Home/Index", request, null,
"json");
C# Mvc Index Controller
public class MyClass
{
public string Begin;
public string End;
}
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Index(
string DateStart,
MyClass []mass)
{
System.Diagnostics.Debug.WriteLine(mass[0].Begin);
}
how to execute this code? thanks.
U can't pass mass: items and expect it to be serialized as a JSON array automatically, you will need to either iterate and construct the JSON (bad plan) or use a JSON library(good plan)
Try write code as below:
var option = {
url: '/Home/Index',
type: 'POST',
data: JSON.stringify(request),
dataType: 'html',
contentType: 'application/json',
success: function(result) {
alert(result);
}
};
$.ajax(option);

Resources