use json format in an URL - asp.net

I am building a rest API with asp.net my problem is that when I try to add a student to my database like that :
http://localhost:50001/api/Students?&FirstName=cc&LastName=cc&Email=student10#gmail.com&DropOut=false&Live=false&ClassId=1&ImageId=1
I get "the value variable is null",
this is my code to add a student:
// Get All Students
[Route("api/Students")]
public IEnumerable<Student> Get()
{
return _StudentService.Queryable().ToList();
}
// Insert Student
[Route("api/Students/")]
public IEnumerable<Student> Post(Student value)
{
cc.Students.Add(value);
cc.SaveChanges();
return Get();
}
I have used "Fiddler web Debugger" to test my URLs an it works only in this way:
now If I have an angularJS client that tries to add a new student to the database,how can I send data as a json format in an URL
this is how I add a new student from my client angularJS:
$http({method: 'POST', url: 'http://localhost:50001/api/Students?&FirstName=cc&LastName=cc&Email=student10#gmail.com&DropOut=false&Live=false&ClassId=1&ImageId=1})
.success(function (data) {
console.log("success");
}).error(function (data, status, headers, config) {
console.log("data error ...");
});
thanks a lot for help

If you are saying you want a true Rest API you should continue to use the POST verb as it is more semantically right for creating a new student.
Passing a new student on the URL is possible but not in the configuration you have provided.
Your API method expects a POST request and that the new student be located in the HTTP body.
Just configure your angular call to use jsonData and post it to your API.

Related

Why asp.net web api return a action after insert data?

This is function to insert a record had generated by VS2019 when add a controller:
// POST: api/Students
[HttpPost]
public async Task<ActionResult<Student>> PostStudent(Student student)
{
_context.Students.Add(student);
await _context.SaveChangesAsync();
return CreatedAtAction("GetStudent", new { id = student.Id }, student);
}
I can't understand Why it using CreatedAtAction to return student, why it not direct return object return student;?
From the docs, given an example:
A 201 status code is generated by the CreatedAtAction method when a product is created. In this code path, the Product object is provided in the response body. A Location response header containing the newly created product's URL is provided.
So, not only does it return the object, but it also includes the url where the new resource can be found.

sending form data with file and boolean values in angular2

I have a form where the user selects from a set of check boxes and also selects a picture. I'm sending this form from an angular2 front-end to an asp.net core web api backend. The issue i am having is that when i send the data, only the image file is sent, all the check box data which is in boolean is ignored. It's my first time doing this so i'm not sure how to handle it.
Below is the code i am using for adding the data to a form data
var formData = new FormData();
formData.append('ReturnFaceLandMarks', this.formViewModel.ReturnFaceLandmarks);
formData.append('ReturnFaceId', this.formViewModel.ReturnFaceId);
formData.append('age', this.formViewModel.age);
formData.append('facial_hair', this.formViewModel.facial_hair);
formData.append('gender', this.formViewModel.gender);
formData.append('glassed', this.formViewModel.glassed);
formData.append('head_pose',"false");
formData.append('smile', "true");
formData.append('file', this.formViewModel.img);
and down here is the post request
detect(data: any): Promise<any>
{
return this.http.post(this.serverUrl+"face/detect/", data, { headers: this.headers })
.toPromise()
.then(response => {
console.log(response);
})
.catch(this.handleError);
}
The file gets sent to my web api, but the only file i see there is the image file.Below is my request payload.
I ran into similar issues working with Angular and .Net
The solution that worked best for me was to either create a class (model) that the FormData mapped to or to specify the web api controller method parameters with the [FromForm] attribute.
public IActionResult Upload(IFormFile file, [FromForm] bool smile) {
...
}

AngularJs Windows Intranet User

Using ASP.Net Web API service I can get the current windows user using the following.
public class UserController : ApiController
{
public string Get()
{
var id = WindowsIdentity.GetCurrent();
return id.Name;
}
}
My question is how can I find the current user logged in a angularjs controller without having to call the web api service?
myApp.controller('TestCtrl', function ($scope) {
$scope.getUserData = function(){
$http({method: 'GET', url: '/URLtoResourceInWebService'}).
success(function(data, status, headers, config) {
//use the data of your User object
}).error(function(data, status, headers, config) {
// called asynchronously if an error occurs
// or server returns response with an error status.
});
}
}); //End of Controller
Here is a real simple example of how to hit an endpoint in Angular and get back a resource from a WebService. I would actually suggest extracting out your API calls however into a service rather than using the "$http" because then you centralize them in one place, and if you switch API's your code doesn't break all over. Let me know if this helps.

A simple POST request to Web API not hitting the API at all

From my MVC application, I am trying to make a POST request to these sample end-points (actions) in an API controller named MembershipController:
[HttpPost]
public string GetFoo([FromBody]string foo)
{
return string.Concat("This is foo: ", foo);
}
[HttpPost]
public string GetBar([FromBody]int bar)
{
return string.Concat("This is bar: ", bar.ToString());
}
[HttpPost]
public IUser CreateNew([FromBody]NewUserAccountInfo newUserAccountInfo)
{
return new User();
}
Here's the client code:
var num = new WebAPIClient().PostAsXmlAsync<int, string>("api/membership/GetBar", 4).Result;
And here's the code for my WebAPIClient class:
public class WebAPIClient
{
private string _baseUri = null;
public WebAPIClient()
{
// TO DO: Make this configurable
_baseUri = "http://localhost:54488/";
}
public async Task<R> PostAsXmlAsync<T, R>(string uri, T value)
{
using (var client = new HttpClient())
{
client.BaseAddress = new Uri(_baseUri);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/xml"));
var requestUri = new Uri(client.BaseAddress, uri);
var response = await client.PostAsXmlAsync<T>(requestUri, value);
response.EnsureSuccessStatusCode();
var taskOfR = await response.Content.ReadAsAsync<R>();
return taskOfR;
}
}
}
I have the following default route defined for the Web API:
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
UPDATE
My code breaks into the debugger until the time the PostAsXmlAsync method on the System.Net.HttpClient code is called. However, no request shows up in Fiddler.
However, if I try to compose a POST request in Fiddler or try to fire a GET request via the browser to one of the API end-points, the POST request composed via Fiddler tells me that I am not sending any data and that I must. The browser sent GET request rightly tells me that the action does not support a GET request.
It just seems like the System.Net.HttpClient class is not sending the POST request properly.
One of the most usual problems is that you don't use the appropriate attribute.
Take into account that there are attributes for ASP.NET MVC and ASP.NET Web API with the same name, but which live in different namespaces:
For Web API you must use the one in System.Web.Http
For MVC, the one in System.Web.MVc
This is a very very usual error, and it affects to allkind of things that exist for both MVC and Web API. So you must be very careful when using something which can exists in bith worlds (for example filters, attributes, or dependency injection registration).
I experienced a similar problem (may not be same one though). In my case, I hadn't given name attribute to the input element. I only figured that out when fiddler showed no post data being sent to the server (just like your case)
<input id="test" name="xyz" type="text" />
Adding the name attribute in the input tag fixed my problem.
However, there is one more thing to note. WebAPI does not put form data into parameters directly. Either you have to create an object with those properties and put that object in the parameter of the post controller. Or you could put no parameters at all like this:
[Route("name/add")]
public async Task Post()
{
if (!Request.Content.IsMimeMultipartContent())
{
return;
}
var provider = PostHelper.GetMultipartProvider();
var result = await Request.Content.ReadAsMultipartAsync(provider);
var clientId = result.FormData["xyz"];
...
Try changing the FromBody to FromUri.
If the parameter is a "simple" type, Web API tries to get the value from the URI. Simple types include the .NET primitive types (int, bool, double, and so forth), plus TimeSpan, DateTime, Guid, decimal, and string, plus any type with a type converter that can convert from a string.
For complex types, Web API tries to read the value from the message body, using a media-type formatter.
Remove FromBody at all and don't make any restrictions in passing parameters (it can be passed at this time either in uri, query string or form submissions (which is kinda a similar to query strings)
[HttpPost]
public string GetFoo(string foo){...}
It will be implicitly parsed and passed.

Strange Behavior when using jQuery/asp.net WebApi

I have 2 Web API Projects:
Api1 is a testing-Environment for the JavaScript Front-End, but has a API
Back-end(the default ValuesController), also for testing.
Api2 is the "true" Back-end, from which the Experimental JavaScript UI schould pull Data. For Testing, i use the default ValuesController here too, because, i want to have the same Output.
Status Quo
The Api1-UI can query the Data from the ValuesController of the own API
The Api2 returns the Correct Data(tested in Firefox and with Fiddler)
The Code
JavaScript Client:
var _load = function (url) {
$.ajax({
url: url,
method: 'GET',
accepts: "application/json; charset=utf-8",
success: function (data) {
alert("Success: " + data);
},
error: function (data) {
alert("Error :" + data);
}
});
};
WebApi Controller method:
public IEnumerable<string> Get()
{
return new string[] { "value1", "value2" };
}
Problem
The JavaScript UI of the experimental Front-End is not able to display, or even receive, the data from the API 2, which is, according to Fiddler, sent correct.
My first thought was, I am using the wrong Method, but i tried $.getJSON and $.ajax. But i always end up with an error. It just says statusText= "Error"
I don't get, why it can display Data from the own ApiController, but not from the "External"...
Thanks for any Help/Suggestions
You seem to be accessing data from X from a different domain Y using ajax. This seems to be a classic cross domain access issue.
You need to set Access-Control-Allow-Origin to value " * " in your response header.
Response.Headers.Add("Access-Control-Allow-Origin", "*")
There various ways you can solve this
defining this header in IIS
using a actionfilter attribute like below
FilterAttribute
public class AllowCrossSiteJsonAttribute : ActionFilterAttribute
{
public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
{
if (actionExecutedContext.Response != null)
actionExecutedContext.Response.Headers.Add("Access-Control-Allow-Origin", "*");
base.OnActionExecuted(actionExecutedContext);
}
}
Using Attribute on Controller Action
[AllowCrossSiteJson]
public Result Get(int id)
{
//return appropriate result
}

Resources