Here is my web api controller:
[HttpGet]
public HttpResponseMessage SensorData(string id)
{
try
{
Responds data = AccessRemote.GetDataFromDevice(id);
DataResponds dataResponds = data.ReturnDatRequest[0];
return Request.CreateResponse(HttpStatusCode.OK, dataResponds);
}
catch (Exception ex)
{
return Request.CreateResponse(HttpStatusCode.Forbidden, ex.Message);
}
}
[HttpGet]
public HttpResponseMessage GetLogs(string GetRecordsById)
{
try
{
IQueryable<SensorInfo> data = sensorResultsRepos.Get();
HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.OK, data);
return response;
}
catch (Exception)
{
throw;
}
}
Here is my resource angularjs definition:
(function () {
"use strict";
angular.module("sensorManagement").factory("SensorResource",
["$resource",
SensorResource])
function SensorResource($resource) {
return $resource("http://localhost:1234/api/SomeData/:id");
}
}());
Here is web api route:
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
"DefaultApiSensor",
"api/{controller}/{id}",
new { controller = "Sensor", id = RouteParameter.Optional }
);
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
At some point I need to access to SensorData action or to GetLogs action using the SensorResource service.
The problem that they are both HTTP GET and both have one parameter.
How can I make call to SensorData and to GetLogs if they in one controller and the have sane http get type?
You can use Attribute Routing to easily solve this problem. See this link for more information regarding this topic.
[HttpGet]
[Route("sensor/{id}")]
public HttpResponseMessage SensorData(string id)
{
try
{
Responds data = AccessRemote.GetDataFromDevice(id);
DataResponds dataResponds = data.ReturnDatRequest[0];
return Request.CreateResponse(HttpStatusCode.OK, dataResponds);
}
catch (Exception ex)
{
return Request.CreateResponse(HttpStatusCode.Forbidden, ex.Message);
}
}
[HttpGet]
[Route("logs/{GetRecordsById}")]
public HttpResponseMessage GetLogs(string GetRecordsById)
{
try
{
IQueryable<SensorInfo> data = sensorResultsRepos.Get();
HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.OK, data);
return response;
}
catch (Exception)
{
throw;
}
}
Related
I am calling a custom Web API from my Angular app, and I need to JSON.parse() my response twice in order to access the properties. I am not sure why this is happening.
/// <summary>
/// Gets list of printers
/// </summary>
[HttpGet]
public IHttpActionResult GetPrinterList()
{
try
{
List<Printer> pl = new List<Printer>();
// List the print server's queues
PrintQueueCollection myPrintQueues = new PrintServer(#"\\LPH-Printers").GetPrintQueues();
foreach (PrintQueue pq in myPrintQueues)
{
Printer p = new Printer();
p.Name = pq.FullName;
pl.Add(p);
}
return Ok(JsonConvert.SerializeObject(pl));
}
catch (Exception e)
{
return BadRequest(e.ToString());
}
}
This is the method in my API, and below is how I am calling it in Angular
'use strict';
app.factory('printerService', ['$http', 'ngAuthSettings', function ($http, ngAuthSettings) {
var serviceBase = ngAuthSettings.apiServiceBaseUri;
var printerServiceFactory = {};
var _DefaultPrinter = function (val) {
return $http.get(serviceBase + 'api/LibertyMobile/GetUserDefaultPrinter', {
params: { 'username': val }
})
};
var _SetDefaultPrinter = function (userName, DefaultPrinter) {
return $http({
url: serviceBase + "api/LibertyMobile/SaveUserDefaultPrinter",
method: "POST",
params: { 'username': userName, 'printer': DefaultPrinter }
});
}
var _GetPrinterList = function () {
return $http.get(serviceBase + 'api/LibertyMobile/GetPrinterList');
}
printerServiceFactory.DefaultPrinter = _DefaultPrinter;
printerServiceFactory.SetDefaultPrinter = _SetDefaultPrinter;
printerServiceFactory.GetPrinterList = _GetPrinterList;
return printerServiceFactory;
}]);
Any help would be greatly appreciated.
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
// Configure Web API to use only bearer token authentication.
config.SuppressDefaultHostAuthentication();
config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));
// Web API routes
config.MapHttpAttributeRoutes();
//config.Routes.MapHttpRoute(
// name: "DefaultApi",
// routeTemplate: "api/{controller}/{id}",
// defaults: new { id = RouteParameter.Optional }
//);
//config.Routes.MapHttpRoute(
// name: "GetPartNumbers",
// routeTemplate: "api/Inventory/GetPartNumbers/{partnum}/{user}",
// defaults: new { controller = "Inventory" }
//);
config.Routes.MapHttpRoute(
name: "ApiByAction",
routeTemplate: "api/{controller}/{action}",
defaults: new { controller = "Inventory", action = RouteParameter.Optional }
);
}
}
Above is my WebApiConfig.cs code.
This
return Ok(JsonConvert.SerializeObject(pl));
The framework will serialize the value passed for you but you are also serializing it using JsonConvert.SerializeObject before passing it to the action result, hence the double serialization.
Just pass the value back
/// <summary>
/// Gets list of printers
/// </summary>
[HttpGet]
public IHttpActionResult GetPrinterList() {
try {
List<Printer> pl = new List<Printer>();
// List the print server's queues
PrintQueueCollection myPrintQueues = new PrintServer(#"\\LPH-Printers").GetPrintQueues();
foreach (PrintQueue pq in myPrintQueues) {
Printer p = new Printer();
p.Name = pq.FullName;
pl.Add(p);
}
return Ok(pl);
} catch (Exception e) {
return BadRequest(e.ToString());
}
}
And let the framework do its thing.
I'm new to angular and trying to make a call to perform crud operations from angular to a newly created mvc webapi controller... cannot get around the 404 not found on the get right now. Looking for some guidance from the pros, thanks!
Angular:
angular.module('PersonApp').service('PersonService', ['$http', function` ($http) {
var PersonService = {};
var urlBase = '/api/PersonApi/';
PersonService.getPersons = function () {
console.log(urlBase);
return $http.get(urlBase);
};
PersonService.upsertPerson = function (person) {
return $http.post(urlBase, person); //must have ,person !!!!!!!!!!
};
PersonService.removePerson = function (id) {
return $http.delete(urlBase + id);
};
return PersonService;
}]);
PersonApi.cs api:
public class PersonApi : ApiController
{
TutorialDataEntities ef_Db = new TutorialDataEntities();
Repository.Repository PersonRepository = new Repository.Repository();
[Route("api/PersonApi/{person}")]
[HttpPost]
public HttpResponseMessage UpsertPerson([FromBody]DTOPerson person)
{
if (ModelState.IsValid) // and if you have any other checks
{
var result = PersonRepository.UpsertPerson(person);
formatDate(result.birthDate);
return Request.CreateResponse(HttpStatusCode.Created, result);
}
return Request.CreateResponse(HttpStatusCode.BadRequest);
}
[Route("api/PersonApi/{id}")]
[HttpDelete]
public HttpResponseMessage RemovePerson([FromUri]int id)
{
PersonRepository.RemovePerson(id);
return Request.CreateResponse(HttpStatusCode.OK);
}
[Route("api/PersonApi/")]
[HttpGet]
public HttpResponseMessage GetPersons()
{
var result = PersonRepository.GetAllPersons();
foreach (var person in result)
{
formatDate(person.birthDate);
}
if (result == null)
return Request.CreateResponse(HttpStatusCode.NotFound);
return Request.CreateResponse(HttpStatusCode.OK, result);
}
private DateTime formatDate(DateTime date)
{
return Convert.ToDateTime(date.ToString("MM/dd/yyyy"));
}
}
My solution explorer:
WebApiConfig.cs
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
Routeconfig.cs
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
I have the following API, which takes care of updating items in the database:
[Route("update")]
[HttpPost("")]
public JsonResult UpdateRecords([FromBody]ICollection<ShoppingItemViewModel> vm)
{
if (ModelState.IsValid)
{
try
{
var items = Mapper.Map<IEnumerable<ShoppingItem>>(vm);
//update database
_repository.UpdateValues(items, User.Identity.Name);
return Json(null);
}
catch (Exception Ex)
{
Response.StatusCode = (int)HttpStatusCode.BadRequest;
return Json(null);
}
}
else
{
Response.StatusCode = (int)HttpStatusCode.BadRequest;
return Json(null);
}
}
Then under my Angular code I am executing this POST method like following:
$scope.SaveChanges = function () {
$http.post("/api/items/update", $scope.items)
.then(function (response) {
}, function (err) {
$scope.errorMessage = "Error occured: " + err;
}).finally(function () {
});
};
What I would like to do, is to introduce new parameters to my initial UpdateRecords function, where some of them are optional. Then depending on the inserted parameters my procedure would do different things.
What I have tried to do is to change my function like following (example):
public JsonResult UpdateRecords([FromBody]ICollection<ShoppingItemViewModel> vm, [FromBody]bool EraseOldItems)
and under my Angular App:
$http.post("/api/items/update", {vm:$scope.items, EraseOldItems: true})
or even
$http.post("/api/items/update", {'vm':$scope.items, 'EraseOldItems': true})
but I could not get the code to work (my parameters were all the time null).
What am I doing wrong here?
From Parameter Binding in ASP.NET Web API:
At most one parameter is allowed to read from the message body.
// Caution: Will not work!
public HttpResponseMessage Post([FromBody] int id, [FromBody] string name) { ... }
The reason for this rule is that the request body might be stored in a
non-buffered stream that can only be read once.
You can pass a request object that contains other objects:
public class Request
{
public ICollection<ShoppingItemViewModel> vm { get; set; }
public bool eraseOldItems { get; set; }
}
And then your action:
[Route("update")]
[HttpPost("")]
public JsonResult UpdateRecords([FromBody]Request request){ ... }
I have this API methods:
namespace Playground.Web.Controllers.API
{
public class FilterConfigurationsController : ApiController
{
private readonly PlaygroundContext _context;
public FilterConfigurationsController()
{
_context = new PlaygroundContext();
}
[HttpPost]
public async Task<IHttpActionResult> Post(Filter data)
{
try
{
var ere = FilterViewModel.GenerateDataForFilters(data, _context);
return Ok(data);
}
catch (Exception ex)
{
throw;
}
}
[HttpPost]
public async Task<IHttpActionResult> Post(IEnumarable<Filter> filterDescriptionList)
{
try
{
var data = FilterViewModel.GenerateDataForFilters(filterDescriptionList, _context);
return Ok();
}
catch (Exception ex)
{
throw;
}
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
_context.Dispose();
}
base.Dispose(disposing);
}
}
}
To call this methods I use this HTTP post calls:
$http.post(config.baseUrl + "api/FilterConfigurations/", scope.filterParams).then(function (result) {});
I am working on web API project and using AngularJS in my project.
This HTTP post call:
$http.get(config.baseUrl + "api/FilterConfigurations/,{data= scope.filterParams[0]}).then(function (result) {});
have to call this method API:
public async Task Post(Filter data)en(function (result) {});
But the method API above never fired.
Instead this method alwaes fired:
public async Task<IHttpActionResult> Post(Filter filterDescriptionList)
Any idea why the API method never fired?
What I am doing wrong?
I am getting 405(Method not found) error in PUT and DELETE requests in my angular and WebAPI. GET and POST are working fine. I have checked all the solutions with this type of error on 'SO' but it didn't worked. I have added required handlers(with PUT/DELETE verbs) in my WebConfig, updated applicationhost.config of IIS EXpress and also uninstalled WebDAV module but still the problem persists.
Here is my controller code:
[RoutePrefix("api/BlogPost")]
public class BlogPostController : ApiController
{
// GET: api/BlogPost
public IQueryable<BlogPostModel> GetblogPostTb()
{
return db.blogPostTb;
}
// GET: api/BlogPost/5
[ResponseType(typeof(BlogPostModel))]
public IHttpActionResult GetBlogPostModel(int id)
{
BlogPostModel blogPostModel = db.blogPostTb.Find(id);
if (blogPostModel == null)
{
return NotFound();
}
return Ok(blogPostModel);
}
// PUT: api/BlogPost/5
[ResponseType(typeof(void))]
public IHttpActionResult PutBlogPostModel(int id, BlogPostModel blogPostModel)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
if (id != blogPostModel.ID)
{
return BadRequest();
}
db.Entry(blogPostModel).State = EntityState.Modified;
try
{
db.SaveChanges();
}
catch (DbUpdateConcurrencyException)
{
if (!BlogPostModelExists(id))
{
return NotFound();
}
else
{
throw;
}
}
return StatusCode(HttpStatusCode.NoContent);
}
[ResponseType(typeof(BlogPostModel))]
public IHttpActionResult DeleteBlogPostModel(int id)
{
BlogPostModel blogPostModel = db.blogPostTb.Find(id);
if (blogPostModel == null)
{
return NotFound();
}
db.blogPostTb.Remove(blogPostModel);
db.SaveChanges();
return Ok(blogPostModel);
}
}
And here is the client side code:
var updateBlogPost = function (id, blogPost) {
return $http.put(blogPostsUrl+"/"+id, blogPost)
.then(function (response) {
return response;
})
Just for the info,I am working with WebAPI2, IIS Express 10 in Visual Studio Community 2015. I am not sure if this is the error of IIS EXpress 10 or Community version of VS.
This seems to be the known issue with attribute routing with WebAPI.
Here update AcceptVerbs and Route attribute with DELETE and PUT methods like this :
[ResponseType(typeof(void))]
[Route("{id:int}")]
[AcceptVerbs("PUT")]
public IHttpActionResult PutBlogPostModel(int id, BlogPostModel blogPostModel)
{
// Your code
}
And Delete as :
[ResponseType(typeof(BlogPostModel))]
[Route("{id:int}")]
[AcceptVerbs("DELETE")]
public IHttpActionResult DeleteBlogPostModel(int id)
{
// Your Code
}
And also use AcceptVerbs attribute for GET method as well because these three(GET,PUT,DELETE) have same URL structure to call their methods.