MVC AngularJs Handling query string - c#

I have CourseAPi Controller that containing follwing method :
public IEnumerable<CoursesDTO> Get(int id)
{
var x = _uniManager.GetCourses(id);
return x;
}
i want to send id from URl to this method using Angualr js
the AngularJs controller :
app.controller('CRUD_OperController', function ($scope, $filter, CRUD_OperService, $location) {
GetAllRecords1();
function GetAllRecords1() {
var id = 12;
var promiseGetSingle = CRUD_OperService.get(id);
promiseGetSingle.then(function (pl)
{ $scope.Courses = pl.data },
function (errorPl) {
// $log.error('Some Error in Getting Records.', errorPl);
});
}
});
My angular service :
app.service('CRUD_OperService', function ($http) {
//Get All Student
this.getAllStudent = function () {
return $http.get("/api/CourseApi/" );
}
//Get Single Records
this.get = function (id) {
return $http.get("/api/CourseApi/" + id);
}
});
my webapi config
public static void Register(HttpConfiguration config)
{
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi1",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
config.EnableSystemDiagnosticsTracing();
}
Update : it return me error
GET http://localhost:54070/api/CourseApi/12 404 (Not Found)

This is the format I have used for such a task:
this.$http({
method: 'GET',
url: 'api/courseapi/' + id
}).then(function (pl) {
$scope.Courses = pl.data
}, function (errorPl) {
$log.error('Some Error in Getting Records.', errorPl);
});
Is this what you are asking?

I can suggest two options:
The first one: configure routes in your angular controller using ng-route, inject $routeParams module and then retrieve the parameters using it. See this link and the Angular doc for more info.
The second option is to get url location and manipulate string in order to get the parameter:
var tokens = $location.absUrl().split("/");
var id = tokens[5]
I prefer the first option, it's "cleaner" than the second. Hope it can help you!

Related

ASP.Net WebAPI 2 404 Error - Insights Say Different

I understand that this question has been asked several times already and I have looked at a lot of the questions, but none of the answers have worked for me thus far.
I am working with an ASP.Net WebAPI 2 Controller using .Net 4.5.2 and posting using Ajax.
I immediately get a 404 error, however looking at insights it shows that there are x amount of requests to that controller and that action\method but its returning a 404 immediately.
This is the the method, and would be grateful if anyone could help me.
[System.Web.Mvc.HttpPost()]
public int InsertRecord(Models.Person model)
{
if (ModelState.IsValid)
{
var person = new Person
{
FirstName = model.FirstName,
LastName = model.LastName,
DateOfBirth = Convert.ToDateTime(model.DateOfBirth)
};
_dbContext.People.Add(person);
_dbContext.SaveChanges();
var id = person.P_id;
return id;
}
else
{
throw new Exception("Invalid Data", null);
}
}
which is being called from my Ajax as follows;
$("#btnSave").click(function () {
$('#FirstName').valid();
$('#LastName').valid();
$('#DateOfBirth').valid();
if ($('#FirstName').valid() &&
$('#LastName').valid() &&
$('#DateOfBirth').valid()) {
//console.log("save clicked");
var jsonData = {
firstName: $('#FirstName').val(),
lastName: $('#LastName').val(),
dateofBirth: $('#DateOfBirth').val()
}
$.ajax(
{
type: "POST", //HTTP POST Method
url: "http://localhost:56658/AddPerson/InsertRecord", // Controller/View
data: jsonData,
success: function (response) {
if (response != null && response.success) {
alert(response.responseText);
} else {
// DoSomethingElse()
alert(response.responseText);
}
},
error: function (response) {
alert("error!"); //
console.log(response);
}
});
return false;
}
});
Edit
public class RouteConfig
{
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 }
);
routes.MapRoute(
name: "AddPerson",
url: "{controller}/{action}",
defaults: new { controller = "AddPerson", action = "InsertRecord"}
);
}
}
Edit 2
This is the global asax file contents
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
GlobalConfiguration.Configure(WebApiConfig.Register);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
Edit 3
public static class WebApiConfig
{
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 }
);
}
}
As this is suppose to be a Wep API it should try to follow that design intent
Check for WebApiConfic where there is usually
public static class WebApiConfig {
public static void Register(HttpConfiguration config) {
// Attribute routing.
config.MapHttpAttributeRoutes();
// Convention-based routing.
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
Notice the api prefix of the default route. This configures how web API endpoints will be called. The api prefix is to avoid route conflicts with the normal MVC framework.
Url would end looking like api/AddPerson
next make sure controller is create properly and follows suggested design. Try to avoid adding too many responsibilities to the controller. Controllers are a UI concern and should be as lean as possible.
public interface IAddPersonCommand {
int? InsertRecord(Models.Person model model);
}
public class PersonController : ApiController {
private readonly IAddPersonCommand service;
public PersonController(IAddPersonCommand service) {
this.service = service;
}
[HttpPost]
public IHttpActionResult Post([FromBody]Models.Person model) {
if (ModelState.IsValid) {
var id = service.InsertRecord(model);
if(id !=null) {
return Ok(id);
}
}
//If we get this far bad request
return BadRequest();
}
}

Multiple HttpPost action with the same parameter in Web API Controller

I'm developing a web application using ASP.NET Web Api and angularJs.
I have a web api controller like this:
[ActionName("AddNewState")]
public object PostAddNewState(RegionInformation newStateParam)
{
RegionOperations regionOperation = new RegionOperations(newStateParam.StateName);
RegionInformation newStateInformation = regionOperation.NewStateInformation;
var text = new
{
newStateInformation
};
return JsonConvert.SerializeObject(text);
}
[ActionName("AddNewCity")]
public object PostAddNewCity(RegionInformation newCityParam)
{
var text = new
{
message="Hello"
};
return JsonConvert.SerializeObject(text);
}
and in client side I have these functions for sending POST request:
$scope.AddNewState = function () {
$http({
method: "POST",
url: "api/RegionManagement/AddNewState",
data: {
StateName: $scope.state
}
}).then(function (response) {
var obj = JSON.parse(response.data);
$scope.States.push({ text: obj.newStateInformation.StateName, value: obj.newStateInformation.ID });
});
};
$scope.AddNewCity = function () {
$http({
method: "POST",
url: "api/RegionManagement/AddNewCity",
data: {
ParentID: $scope.RegionInptes.ParentID,
CityName: $scope.city
}
}).then(function (response) {
var obj = JSON.parse(response.data);
alert(obj.message);
});
};
When I execute $scope.AddNewCity or $scope.AddNewState I face with 500 Internal Server Error.if I comment AddNewCity action in web api controller then I can execute $scope.AddNewState successfully.
I searched for using multiple HTTPPost in a web api controller and try this solution: Multiple HttpPost method in Web API controller, but nothing happened and I still have that error.
UPDATE
This is my config file:
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "ControllerOnly",
routeTemplate: "api/{controller}"
);
config.Routes.MapHttpRoute(
name: "ControllerandId",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
config.Routes.MapHttpRoute(
name: "ControllerAndAction",
routeTemplate: "api/{controller}/{action}"
);
}
The order in which you register your routes is important. register more specific routes first and the more general routes after.
public static void Register(HttpConfiguration config) {
// Web API configuration and services
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "ControllerAndAction",
routeTemplate: "api/{controller}/{action}/{id}"
defaults: new { id = RouteParameter.Optional }
);
config.Routes.MapHttpRoute(
name: "ControllerandId",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
You should also update the controller to be a little more specific as to what it can handle.
public class RegionManagementController : ApiController {
[HttpPost]
[ActionName("AddNewState")]
public object PostAddNewState(RegionInformation newStateParam) { ... }
[HttpPost]
[ActionName("AddNewCity")]
public object PostAddNewCity(RegionInformation newCityParam) { ... }
}
May be this is because of the number of parameters in the request url
[ActionName("AddNewState")]
public object PostAddNewState(RegionInformation newStateParam)
{
RegionOperations regionOperation = new RegionOperations(newStateParam.StateName);
RegionInformation newStateInformation = regionOperation.NewStateInformation;
var text = new
{
newStateInformation
};
return JsonConvert.SerializeObject(text);
}
[ActionName("AddNewCity")]
public object PostAddNewCity(RegionInformation newCityParam)
{
RegionOperations regionOperation = new RegionOperations(newCityParam.ParentID, newCityParam.CityName);
RegionInformation newStateInformation = regionOperation.NewStateInformation;
var text = new
{
newStateInformation
};
return JsonConvert.SerializeObject(text);
}

MVC Cannot access API Controller actions

I am currently unable to access my api controller actions. I have an MVC app which calls the api through ajax calls in my javascript.
My API method is:
[HttpPost, Route("api/Communication/AddLink")]
public HttpResponseMessage AddLink([FromBody]int id)
{
//DO STUFF
return Request.CreateResponse(HttpStatusCode.OK, returnData);
}
my ajax call is:
$.ajax({
cache: false,
url: serviceEndpoint + 'api/Communication/AddLink',
type: 'POST',
data: { id: commid },
headers:{
Authorization: 'Bearer ' + token
},
success: function (data) {
console.log(data);
}
});
I retrieve my token as follows:
public async static Task<AuthenticationResult> GetTokenAsync(AuthenticationContext ctx, string resourceId)
{
ClientCredential credential = new ClientCredential(OfficeSettings.ClientId, OfficeSettings.ClientSecret);
var userObjectId = ClaimsPrincipal.Current.FindFirst("http://schemas.microsoft.com/identity/claims/objectidentifier").Value;
UserIdentifier ident = new UserIdentifier(userObjectId, UserIdentifierType.UniqueId);
var redirectUrl = new Uri(HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Path));
try
{
AuthenticationResult result = await ctx.AcquireTokenSilentAsync(resourceId, credential, ident);
//var result = await ctx.AcquireTokenAsync(resourceId, credential);
LastAuthority = ctx.Authority;
return result;
}
catch (AdalException e)
{
logger.Error(e, "AcquireTokenSilentAsync: " + e.Message);
ctx.TokenCache.Clear();
return null;
}
catch (Exception ex)
{
throw ex;
}
}
and here is my routing from my WebApiConfig.cs:
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
config.EnableCors();
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApiWithAction",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
// DI Config
var container = new UnityContainer();
/// Register Types
container.RegisterType<IUnitOfWork, UnitOfWork>(new HierarchicalLifetimeManager());
config.DependencyResolver = new UnityResolver(container);
}
This works in fiddler if i add the [AllowAnonymous] attribute to my API action but doesnt work inside the app however for obvious reasons this is not a solution.
When i attempt it through fiddler i get the error:
IDX10803: Unable to create to obtain configuration from: 'https://login.microsoftonline.com/.well-known/openid-configuration'
Any help with this would be greatly appreciated as i am out of ideas on this one. I am happy to provide further code and info if needed.
Thanks,
EDIT
A little additional info. My Api is set to start at localhost:44391 however when its loaded the url is https://localhost:44391/Error/GenericError. Does this possibly indicate something has gone wrong on start up? If so how do i debug this correctly?

How write right route to REST Api Controller with get method

I have MVC Web Api project. Based on this project I created REST Api controller:
public class ViewConfigFileController : ApiController
{
public string Get()
{
string result = string.Empty;
try
{
result = File.ReadAllText(System.Web.Hosting.HostingEnvironment.MapPath("~/Config/configData.xml"));
}
catch (Exception)
{
result = "Error read XML file!";
}
return result;
}
}
I want create manual route:
routes.MapRoute(
name: "ViewConfigFile",
url: "ViewConfigFile/Get/{id}",
defaults: new { controller = "ViewConfigFile", action = "Get", id = UrlParameter.Optional }
);
After start application I see error: Application doesn't found.
So, How can I fix it?
Thanks in advance.
You need "{controller}" and "{action}" placeholder in your route config.
Try change your route config to following one.
routes.MapRoute(
name: "ViewConfigFile",
url: "{controller}/{action}/{id}",
defaults: new { controller = "ViewConfigFile", action = "Get", id = UrlParameter.Optional }
);

Trying to call a specific GET method on my WebAPI, but getting HTTP 404 Not Found

I'm making a call to http://localhost/AppTools.WebAPI/api/BulletinBoard/GetMessagesForApp/AppName, but it's returning a 404 error. I think this has to do with routing, but I'm not sure.
Here's the Web API method inside my BulletinBoard controller:
[HttpGet]
public HttpResponseMessage GetMessagesForApp(string id)
{
// get current, valid messages
var messages = (from i in db.BulletinBoards
where i.AppId == id &&
DateTime.Today >= i.DisplayFrom &&
DateTime.Today <= i.DisplayTo &&
i.IsActive == true
select new
{
Message = i.Message,
IntervalId = i.IntervalId,
Interval = i.Interval.IntervalDescription,
Timeout = i.Timout,
})
.ToList();
HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.OK, messages);
return response;
}
Here's my 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 }
);
}
The standard Get() and Get(int id) work fine, I didn't change the method name or signatures. Get() returns a complete list of records, Get(int id) returns a specific record. I want GetMessagesByApp(string id) to return a list of records specific to a certain AppName. Can you tell why this isn't working?
Here's my RouteConfig.cs:
The RouteConfig.cs file is used to define the routes for your ASP.NET MVC controllers. Those have absolutely nothing to do with the routes used by your Web API controllers. They are defined in the WebApiConfig.cs file.
So make sure you have declared your routes in the proper place:
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.Routes.MapHttpRoute(
name: "ApiWithActionName",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
Notice that I have added a custom route before the default one which will allow you to achieve the desired url pattern.
And then you could have the following controller action which will work fine:
// GET /api/controllername
// GET /api/controllername/get
[HttpGet]
public HttpResponseMessage Get()
{
...
}
// GET /api/controllername/get/123
[HttpGet]
public HttpResponseMessage Get(int id)
{
...
}
// GET /api/controllername/GetMessagesForApp/abc
[HttpGet]
public HttpResponseMessage GetMessagesForApp(string id)
{
...
}

Categories

Resources