Get data from HttpContext Angular and Web API - c#

In the angular controller I have this code to transfer $scope.myModel to a Web API controller:
$scope.upload[index] = $upload.upload({
url: settings.constants.uploadURL,
headers: { 'myHeaderKey': 'myHeaderVal' },
data: { model: $scope.myModel },
file: $file,
fileFormDataName: 'myFile'
}).then(function (response) { ...
The Web API controller post method looks like this
public HttpResponseMessage Post()
{
return UploadFile(HttpContext.Current);
}
How do I get the data: model from out from the HttpContext??

WebAPI is not designed to be used in that fashion. Specifically, it is usually bad practice to refer to HttpContext.Current from within a WebAPI controller method. If you did want to check the request or response, you should refer to them by the properties of the ApiController base class, see the msdn docs.
Usually, people prefer model binding for situations like this. Suppose you had in js:
{
foo: "bar"
}
You should declare a class in C# that maps to it:
public class MyRequestModel
{
public string Foo { get; set; }
}
And by declaring your API method:
public HttpResponseMessage Post(MyRequestModel mdl)
{
// do stuff, mdl.Foo will have "bar" in it magically
}
This results in more object-oriented ways of transferring data from javascript to C#. It's more typesafe because you can be guaranteed that the Foo property in C# will have a string, or an int, or whatever you declare it to be as opposed to parsing the request yourself.

Related

Unable to post serilizable object from $http to web api

web api has [Serilizable] model objects as that needs for serilization intense.
Now, when I post that model object from $.http call using below code then, it post without error but, no data populate and all values are null posted on web api.
If I remove [Serilizable] attribute then works fine and able to get all posted value.
return $http({
method: "POST",
url: config.APIURL + 'Parts',
data: JSON.stringify(part), // Strinify your object
headers: { 'Content-Type': 'application/json' }
});
web api POST method taking parameter as below object:
[Serializable]
public class Part
{
public double? PartLength { get; set; }
}
Please help me here.
Found the solution finally. Need to mark the object with [JsonObject],[JsonProperty] attributes as below.
[Serializable]
[JsonObject]
public class SNPart
{
[JsonProperty]
public double? PartLength { get; set; }
[JsonProperty]
thanks
dhaval

Getting angular ajax data in asp.net mvc6

I've been trying to figure this out for hours now but none of the solutions seem to help. I have an MVC6 project with AngularJs. I am able to connect, so my routes are working, and I am able to get data back if I hard code a string or something, but I can't seem to access the data sent to the server.
My angularjs http request code:
var app = angular.module('APIService', []);
app.factory('APIService', function ($http) {
var api = {};
api.getBuyer = function (data) {
return $http.post('/api/buyer', data);
}
return api;
});
The angularjs function call
APIService.getBuyer({ Url: 'samirbashir5739', FirstName: 'Samir' }).success(function (res) {
});
My C# Controller
namespace Reporting.api
{
[Route("api/buyer")]
public class BuyersController : Controller
{
// POST api/buyer
[HttpPost]
public string Post([FromBody] string Url)
{
return Url;
}
}
}
I've tried setting the data as "JsonResult data", or even "string Url." Most tutorials I found had an object for the data so it would fit into something like "[FromBody] Buyer buyer" but I don't have an object for it, I simply want the data. Is it possible?
WebApi does not support multiple parameter binding from a post request. You can check more details here.
So the proper way for the WebApi is to create a request model that will contain all the properties that will be bound. Perhaps you can try multiple [FromUri] parameters, but then you will have to add them to the url yourself in angualr, rather than just pass to .post.
Example model:
public class RequestModel
{
public string Url {get;set;}
public string Name {get;set;}
}
I also believe that adding the model improves the structure of your code as you always know what your server expects rather than working with some dynamic data.
P.S. Did not notice that you use ASP.Net Core, my data is from web api 2, but perhaps it's still valid, so you will need to create a model + FromBody should not be required on post requests since it's the default behavior.
I think your controller is wrong. You are trying to pass a Url and a name whereas your controller method is waiting for a single Url.
Try to pass only a Url and it should work.
If you want to pass the Url and the Firstname, you have to modify your controller method like this :
[HttpPost]
public string Post([FromBody] string Url, string FirstName)
{
// Do whatever you need to do here ...
}

Pass two parameters to WEB API call using angular post

I have the following post method in my WEB API controller:
public async Task<HttpResponseMessage> SendPost(Application application)
I call it through javascript using angular.js $http.post and pass through the application parameter as JSON:
$http.post("/api/AController/SendPost", JSON.stringify(application)).
success(function (data, status, headers, config) {
}
This works.
Now I want to pass through a second parameter as a simple string (I can't modify the existing application JSON object).I tried a few different ways suggested on the web but none of them seem to work. I need to be able to do soemthing like this:
Controller:
public async Task<HttpResponseMessage> SendPost(RentalApplication application,string test)
Javascript:
$http.post("/api/TessIntegration/SendPost", {application:JSON.stringify(application),test:"Some value"}).
success(function (data, status, headers, config) {
}
You cannot get multiple objects from the body in WebAPI.
If you were passing two complex objects, the solution would be to wrap them into another complex object.
public async Task<HttpResponseMessage> SendPost(SuperComplex request)
public class SuperComplex {
public Application Application { get; set; }
public AnotherObject Object { get; set; }
}
$http.post("/api/AController/SendPost", { application: application, Object: {} });
Now if the 2nd parameters is a simple object (such as a string) you can just pass it by queryString instead.
$http.post("/api/AController/SendPost?test=some+value", application );
Also, you don't have to stringify, Angular does it for you.
Found a solution using Newtonsoft.Json.Linq.JObject:
Controller:
public async Task<HttpResponseMessage> SendPost(JObject data)
{
RentalApplication application = data["application"].ToObject<RentalApplication>();
string test = data["test"].ToObject<string>();
}
Javascript:
var data = {
application : application,
test : "sample value"
};
$http.post("/api/TessIntegration/SendPost",data).
success(function (data, status, headers, config) {
}
Update to #Denys answer. Use of JObject is not necessary. Simply use JSON.stringify(data) in your javascript as:
JAVASCRIPT:
var data = {
application : application,
test : "sample value"
};
$http.post("/api/TessIntegration/SendPost",data).
success(function (JSON.stringify(data), status, headers, config) {
C#
Change definition of controller endpoint as:
public async Task<HttpResponseMessage> SendPost(RentalApplication application, string test)
{
RentalApplication application = data["application"].ToObject<RentalApplication>();
string test = data["test"].ToObject<string>();
}

How define and call an api Post in c#

I have created POST/GET request in MVC before.
In my HomeController
[HttpPost]
public string Index(int Value)
{
return Value.ToString();
}
And setting chrome extension POSTMAN with a form-data
I can call http://localhost/mvcApp/ with a variable 'Value' with value '1' and get a string '1' in return
But when I create a surveyController : ApiController doesn't work when I call http://localhost/mvcApp/api/survey/
public string Post(int Value)
{
return Value.ToString();
}
"Message": "No HTTP resource was found that matches the request URI 'http://localhost/mvcApp/api/survey/'.",
"MessageDetail": "No action was found on the controller 'survey' that matches the request."
I'm not sure if the error is in the way the api is created, or in the way the POSTMAN is trying to call the api. Because that '.'
Also try in my HomeControler Index
client.BaseAddress = new Uri("http://localhost/mvcApp");
var result = client.PostAsync("/api/survey", new
{
Value = 1
}, new JsonMediaTypeFormatter()).Result;
if (result.IsSuccessStatusCode) // here return Not found
The WebApi controllers' conventions are not the same as those of plain ol' MVC controllers.
Basically the problem is that you can't specify the int parameter the way you did.
Try this in you WebApi controller:
// nested helper class
public class PostParams {
public int Value { get; set; }
}
public string Post(PostParams parameters) {
return parameters.Value.ToString();
}
and see how that works.
Here's a thorough article on passing parameters within POST requests to WebAPI controllers:
Passing-multiple-POST-parameters-to-Web-API-Controller-Methods
Long story short, these are the conventions, roughly speaking:
you can't capture POST form name-value pairs in parameters
you can capture them inside the properties of a class if that class is the parameter type of one of your method's parameters
you can capture query parameters in method parameters
EDIT
If you wish to test your WebAPI server using C# you could follow these steps:
Create a nice Console Application (preferably within the same solution)
Add the Web API Client NuGet package to this Console Application
Make your Program.cs do something like this.
The following code uses the C# 5.0 async and await operators.
It also uses the Task class and anonymous types.
I've pointed out official MSDN articles (click on the links) should you be interested in what those things are.
using System.Net.Http;
using System.Threading.Tasks;
namespace ConsoleApplication1 {
class Program {
public static void Main(string[] args) {
Test().Wait();
}
private static async Task Test() {
HttpClient client = new HttpClient();
await client.PostAsJsonAsync(
"http://localhost/mvcApp/api/survey/",
new {
value = 10
}
);
}
}
}
This wasnt easy. After lot of reading I solve it like this.
First the api controler need to define the input parameter with the [FromBody] attribute
// POST api/survey
public void Post([FromBody]string value)
{
}
For testing I put a button in the view and use an Ajax / Post, the variable name need to be an empty string before the variable value.
$(document).ready(
$('#post').click(function () {
var url = 'http://localhost/mvcApi/api/survey';
var data = { "": 'Hola' }; // Define a simple variable this way
$.ajax({
type: "POST",
url: url,
data: data,
success: sucess
}
});
})
Or if you want send mutliple values
data = { "": ["update one", "update two", "update three"] };
But if you want receive an object
public void Post(Survey data)
{
string value = data.Value.ToString();
}
$('#post').click(function () {
....
var data = { value: 25 }
More info here Sending Data and here Binding

Posting and receiving json with MVC Web API

I have seen similar case to mine answered but I have specific need that always differed from others problem.
I am sending json data from my html page to the MVC Web API. Unfortunately the data I am receiving is ALWAYS null (I have tried a lot of different things here). The thing is I really need to received the data as json (string), because my data is very complex and cannot be simply deserialized by the Web API (I have my own custom deserializer that does it).
Heres the code!
First, the web api controller that will receive the ajax post request
public class ActivityController : ApiController
{
// POST api/activity
public string Post([FromBody]string json)
{
}
}
Then, the ajax request itself
$.ajax("/api/activity", {
contentType: "application/json",
data: { json: ko.mapping.toJSON(fusionedModel) },
type: "POST",
success: function (result) {
...
}
});
As far as the data is concerned, it is rendered well (I've used that same request with MVC (not Web Api) and the server was receiving the string perfectly... now for some reason, in my web api controller, the "json" param is ALWAYS null. As I said before, it is IMPORTANT that I receive the data as a json string.
EDIT : I found that my question is a duplicate of this one : POST JSON with MVC 4 API Controller
But I really don't like the answer... having to create an object just to encapsulate the string is very dirty...
I recommend you avoid using standard body parameter binding as that mechanism assumes that you are trying to deserialize the body into a CLR object. Try this,
public class ActivityController : ApiController
{
// POST api/activity
public async Task<HttpResponseMessage> Post(HttpRequestMessage request)
{
var jsonString = await request.Content.ReadAsStringAsync();
return new HttpResponseMessage();
}
}
If you really want to use parameter binding, you can do this.
public HttpResponseMessage Post(JToken jToken)
{
return new HttpResponseMessage()
{
Content = new StringContent(jToken.ToString())
};
}
Please try to use the [HttpPost] Attribute that can be located on System.Web.Http;
public class ActivityController : ApiController
{
// POST api/activity
[HttpPost]
public string Post([FromBody]string json)
{
}
}
I could be wrong here, but it looks like you haven't included your action in the post URL. Try changing
$.ajax("/api/activity", {
contentType: "application/json",
data: { json: ko.mapping.toJSON(fusionedModel) },
type: "POST",
success: function (result) {
...
}
});
To
$.ajax("/api/activity/POST", {
contentType: "application/json",
data: { json: ko.mapping.toJSON(fusionedModel) },
type: "POST",
success: function (result) {
...
}
});

Categories