Post Data Using AngularJS to MVC 4 Web API - asp.net-mvc

**AngularJs Post Request :**
var url = 'http://localhost:54047/api/JobSaleBid';
var student = {
"firstname": 'dfdsfsdfsdfsdfsdfsdf',
"lastname": 'k.waqas26#gmail.com'
};
data = $http.post(
url,
JSON.stringify(student),
{
headers: {
'Content-Type': 'application/json'
}
}
).success(function (data) {
$scope.person = data;
});
**Model:**
public class student
{
public string firstname {get;set;}
public string lastname {get;set;}
}
**Controller:**
public class JobSaleBidController : BaseApiController
{
public string Post([FromBody]student model)
{
return JsonConvert.SerializeObject(model);
}
}
**Route Config**
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
While Posting I am getting the following errors
Failed to load resource: the server responded with a status of 405 (Method Not Allowed)
index.html:1 XMLHttpRequest cannot load http://localhost:54047/api/JobSaleBid. Invalid HTTP status code 405
Request Detail:
Remote Address:127.0.0.1:54047
Request URL:http://localhost:54047/api/JobSaleBid
Request Method:OPTIONS
Status Code:405 Method Not Allowed
The requested resource does not support http method 'GET'.
Can any one tell me what is wrong, I have tried so many solutions but still not getting it worked, you help will be appreciated.

The jquery post should look like this
$http({
method: 'POST',
url: url,
data: JSON.stringify(student),
headers: {'Content-Type': 'application/json'}
});
and would strongly recommend you to use a Service/Factory to get data and inject them in your controller and then use them.
Edit:
Try adding [HttpPost] over your action.

Have a look at this page: http://www.asp.net/web-api/overview/testing-and-debugging/troubleshooting-http-405-errors-after-publishing-web-api-applications
I've encountered the same problem before. For me, adding the ExtensionlessUrlHandler fixed the problem.

Related

Post method returns 404 in Asp.net core Web API Controller

Routes code below:
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
Controller code below :
// POST api/values
[HttpPost]
public void Post([FromBody]Employee employee)
{
employeeManager.CreateAsync(employee);
}
All other methods working except the post method.
call from angular component :
onSubmit(employeeItems: any) {
console.log(employeeItems);
this.getData();
var headers = new Headers();
headers.append('Content-Type', 'application/json; charset=utf-8');
this.http.post('api/Employee/Post', employeeItems, { headers: headers }).subscribe();
this.createEmployeeFlag = false;
}
I tried even from Postman, but no luck.
Your url and route templates do not match
[Route("api/[controller]")]
public class EmployeeController : Controller {
[HttpPost]
public async Task<IActionResult> Post([FromBody]Employee employee) {
await employeeManager.CreateAsync(employee);
return Ok();
}
}
and update your calling URL to call the default endpoint api/Employee
onSubmit(employeeItems: any) {
console.log(employeeItems);
this.getData();
var headers = new Headers();
headers.append('Content-Type', 'application/json; charset=utf-8');
this.http.post('api/Employee', employeeItems, { headers: headers }).subscribe();
this.createEmployeeFlag = false;
}
This is the code that you would need in your service, there are two issues here, first is the URL, it needs to be the complete URL path. The second is is that you are trying to subscribe to something before mapping it to a Observable
onSubmit(employeeItems: any) {
let url: string = 'http://localhost/api/employee'; //this will be the complete url that you would hit with say postman
this.getData(); //I'm not sure what this is so I'm leaving it here
this.http.post(url, employeeItems)
.map((response: Response) => response.json())
.Subscribe((response: any) => {
//do whatever with the response here.
});
this.createEmployeeFlag = false;
}
I would suggest breaking this up into a *.service.ts file.
*.service.ts
public postEmployee(employeeItems: any): Observable<any> {
let url: string = 'http://localhost/api/employee'; //this will be the complete url that you would hit with say postman
this.http.post(url, employeeItems)
.map((response: Response) => response.json());
}
inside your *.component.ts
constructor(private service: Service) {}
onSubmit(employeeItems: any) {
this.getData(); //I'm not sure what this is so I'm leaving it here
this.service.postEmployee(employeeItems)
.Subscribe((response: any) => {
//do whatever with the response here.
});
this.createEmployeeFlag = false;
}

How to configure Odata api for show result from table or stored procedure

I am going to create an Odata api in asp.net mvc 4 for get data from new table. when I call the Odata method and use debug in the code It shows me data properly. But when it comes to browser, it shows empty screen.
There is no error shown in the code.
this is my Odata method :
[Queryable]
public HCPData GetHCPData([FromODataUri] int key)
{
// return SingleResult.Create(db.HCPDatas.Where(hcpdata => hcpdata.Id == key));
IQueryable<HCPData> result = db.HCPDatas.Where(p => p.CompanyId == key);
return result.FirstOrDefault();
}
this is my WebApiConfig method:
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
ODataModelBuilder modelBuilder = new ODataConventionModelBuilder();
//var entitySetConfiguration1 = modelBuilder.EntitySet<Job>("Job");
var entitySetConfiguration1 = modelBuilder.EntitySet<HCPData>("HCPData");
var customer = modelBuilder.EntityType<HCPData>();
modelBuilder.EntitySet<HCPData>("HCPData");
config.MapODataServiceRoute(
routeName: "ODataRoute",
routePrefix: null,
model: modelBuilder.GetEdmModel());
}
When I checked the console of empty screen in browser it shows an error: "NetworkError: 406 Not Acceptable - http://localhost:50369/HCPData?key=11"
Please let me know the solution of the issue. Thanks in advance.
What's the result if you change the controller as follows:
public class HCPDataController : ODataController
{
[EnableQuery]
public HCPData GetHCPData([FromODataUri] int key)
{
...
}
}
[My Sample]
Because, at my side, if I implement the controller as follows, it can work:
[EnableQuery]
public HCPData GetHCPData([FromODataUri] int key)
{
var data = new HCPData
{
CompanyId = 2,
Name = "Key = " + key
};
return data;
}
Example:
Let me issue the following request:
I can get the following response:
{
"#odata.context":"http://localhost:62591/odata/$metadata#HCPData/$entity","CompanyId":2,"Name":"Key = 11"
}

WebApi POST request gets handled by GET

I'm using RestSharp to consume my WebApi. Here is the relevant code:
var insertRequest = new RestRequest("MappedSystem", Method.POST);
insertRequest.AddBody(new MappedSystemCreateModel
{
MappedSystemDetails = new MappedSystemCreateModel.Details
{
SystemName = "TestName",
SystemVersion = "TV"
}
});
var response = RestClient.Execute(insertRequest);
But when I debug my WebApi it hits the Get() method:
public class MappedSystemController : ApiController
{
private readonly IMappedSystemService _mappedSystemService;
public MappedSystemController(IMappedSystemService mappedSystemService)
{
_mappedSystemService = mappedSystemService;
}
public MappedSystemViewModel[] Get()
{
=> return _mappedSystemService.Get();
}
public MappedSystemViewModel Get(Guid id)
{
return _mappedSystemService.Get(id);
}
[HttpPost]
public MappedSystemViewModel Post([FromBody]MappedSystemCreateModel model)
{
return _mappedSystemService.Post(model);
}
}
I think there must be something wrong with my routeConfig, but I don't know at this point:
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}/{id2}/",
defaults: new { id = RouteParameter.Optional, id2 = RouteParameter.Optional }
);
There was a Post route handler interceptor checking to see if I had correctly added a trailing '/'. Since I hadn't it responded with a 301 and redirected. Somehow/somewhere in the RedirectPermanently() the Verb was getting lost. The answer was to originally make the request with the trailing '/'. But of course this does shed light on the error found in the redirect.
Also, I needed this following code on the request or the body wouldn't deserialize:
insertRequest.RequestFormat = DataFormat.Json;

Passing Dynamic JSON Object to Web API - Newtonsoft Example

I need to pass a dynamic JSON object to my Web API controller so that I can process it depending on what type it is. I have tried using the JSON.NET example that can be seen here but when I use Fiddler, I can see that the passed in JObect is always null.
This is an exert from the example pasted into Fiddler:
POST http://localhost:9185/api/Auto/PostSavePage/ HTTP/1.1
User-Agent: Fiddler
Content-type: application/json
Host: localhost
Content-Length: 88
{AlbumName: "Dirty Deeds",Songs:[ { SongName: "Problem Child"},{ SongName:
"Squealer"}]}
Ans here is my very simple Web API controller method:
[HttpPost]
public JObject PostSavePage(JObject jObject)
{
dynamic testObject = jObject;
// other stuff here
}
I am new to this and I have a couple of questions around this area:
Am I doing something wrong in this particular example?
Arguably, more importantly, is there a better way to pass in a dynamic JSON object (from an JavaScript AJAX post)?
As per Perception's comment your JSON doesn't look valid. Run it through JSONLint and you get:
Parse error on line 1:
{ AlbumName: "Dirty De
-----^
Expecting 'STRING', '}'
Change it to have " around the field names:
{
"AlbumName": "Dirty Deeds",
"Songs": [
{
"SongName": "Problem Child"
},
{
"SongName": "Squealer"
}
]
}
Also have you tried swapping out your JObject for either a JToken or a Dynamic object (e.g. here)?
[HttpPost]
public JObject PostSavePage(JToken testObject)
{
// other stuff here
}
OR
[HttpPost]
public JObject PostSavePage(dynamic testObject)
{
// other stuff here
}
Thanks to everyone who helped here. Unfortunately, I never got to the bottom of what was wrong.
I ported the project over piece by piece to a new project and it works fine.
For info, I have a RouteConfig class, which is quite simple at the moment:
public class RouteConfig
{
private static string ControllerAction = "ApiControllerAction";
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapHttpRoute(
name: ControllerAction,
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
My call into the API now uses JSON.Stringify:
$.ajax("http://localhost:54997/api/values/PostSavePage/", {
data: JSON.stringify(jObject),
contentType: 'application/json',
type: 'POST'
});
The original API action works.
Note, that I'm only playing with this at the moment so the code is not the best but I thought it may be useful in basic form in case someone else has a similar issue.

Get Data From JSONP Request In Asp.Net Web Api

I am trying to POST data to an Asp.Net Web API on another one of my domains. I need to support IE9/8 so CORS won't cut it. When I make a call like this:
$.ajax({
type: "GET",
url: "http://www.myotherdomain.com/account",
data: "{firstName:'John', lastName:'Smith'}",
contentType: "application/json; charset=utf-8",
dataType: "jsonp",
success: function(msg) {
console.log(msg);
},
error: function(x, e) {
console.log(x);
}
});​
it makes a GET request to:
http://www.myotherdomain.com/account?
callback=jQuery18008523724081460387_1347223856707&
{firstName:'John',%20lastName:'Smith'}&
_=1347223856725
I've implemented this JSONP Formatter for ASP.NET Web API and my server responds with a properly formatted JSONP response. I don't understand how to register a route to consume an account object.
config.Routes.MapHttpRoute(
name: "Account",
routeTemplate: "account",
defaults: new { controller = "account", account = RouteParameter.Optional }
);
How do I deserialize an object from a querystring parameter without name?
Instead of using JSON you could send the parameters as query string values. Let's suppose that you have the following model:
public class User
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
and the following API controller:
public class AccountController : ApiController
{
public HttpResponseMessage Get([FromUri]User user)
{
return Request.CreateResponse(HttpStatusCode.OK, new { foo = "bar" });
}
}
which could be consumed like that:
$.ajax({
type: 'GET',
url: 'http://www.myotherdomain.com/account?callback=?',
data: { firstName: 'John', lastName: 'Smith' },
dataType: 'jsonp',
success: function (msg) {
console.log(msg);
},
error: function (x, e) {
console.log(x);
}
});

Resources