I have an asp.net webforms application as my UI layer. This application is responsible for sending an object list down to my DAL Class Library which will then send this object list to a WebAPI for processing.
The WebAPI needs to retrieve the object list, do the processing and send an OK status code back.
Is this possible? If is there any good documentation on how this is done?
Here is what I have in my webforms app:
public static async Task<bool> MyFunction(IList<string> Ids)
{
using (var client = new HttpClient())
{
bool success = false;
client.BaseAddress = new Uri("http://localhost:9000/");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
// HTTP GET
HttpResponseMessage response = await client.GetAsync("api/products/MyProcessFunctionName");
if (response.IsSuccessStatusCode)
{
success = true;
}
return success;
}
}
I need to figure out how to send the list of string Ids to the WebApi processing function as a parameter.
I assume that you already know how to setup Web API controller in your project.
Here is a code sample for sending data from UI back to Web API controller method, which will then save that data in database,
Step 1:
In your front-end, I hope you will have a custom javascript file which handles any button click event. On that, try to send the data from UI to Web API using a POST method as shown below,
var StaffSaveRequest = {};
StaffSaveRequest.StaffDetails = {};
StaffSaveRequest.StaffDetails.Name = "Test Name";
$.ajax({
url: 'api/Staff/SaveStaff', //this is the path to web api controller method
type: 'POST',
dataType: 'json',
data: StaffSaveRequest,
success: function (response, textStatus, xhr) {
//handle success
},
error: function (xhr, textStatus, errorThrown) {
if (textStatus != 'abort') {
//handle error
}
}
});
Step 2:
Add a controller class as shown below and see the inline comments. This controller class will then interact with method in Data Access layer for saving any information.
public class StaffController : ApiController //inherits ApiController
{
[HttpPost] //add post attribute
public HttpResponseMessage SaveStaff(StaffSaveRequest staffSaveRequest)
{
try
{
var result = StaffManager.Save(staffSaveRequest);//save in database using a method in data access layer
return Request.CreateResponse(HttpStatusCode.OK, result);//result the response back
}
catch (Exception ex)
{
//log error
}
}
I hope this will give you some idea on where and how to start. Reply back, if you still have issues/questions.
You can use the Microsoft.AspNet.WebApi.Client to use your restful API.
Here is an official example from the asp.net site:
http://www.asp.net/web-api/overview/advanced/calling-a-web-api-from-a-net-client
If you need call your custom function MyProcessFunction first you need to define the function in the controller
public IEnumerable<string> MyProcessFunctionName()
{
return new string[] { "value1", "value2" };
}
after that, if you need to call it by name client.GetAsync("api/products/MyProcessFunctionName") you need to change the RouteConfig file to allow API calls by action name:
Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { action = "get", id = RouteParameter.Optional }
);
It's possible to call WebApi from your webforms project. Here is a sample using WPF to call WebApi, but call should be same for webforms:
http://www.codeproject.com/Articles/611176/Calling-ASP-Net-WebAPI-using-HttpClient
Related
i acan use ajax and api action in one project and send data and update data correctly.
but when i want to send data from ajax in my project to api action in my another project,the api action dont work!
$.ajax({
type: "post",
url: urll,
error: function() {
alert("errore")
},
data: {
id: 4
},
success: function(dataa) {
alert("ok");
var x = JSON.stringify(dataa, null, '\t');
var dataaa = $.parseJSON(x);
alert(dataaa.price);
dataa.price -= 1.02;
var url2 = 'https://localhost:44337/api/apiialbums/PutAlbum';
//var url2 = 'http://localhost:51111/api/AlbumsApi/PutAlbum';
$.ajax({
type: "PUt",
//async: false,
url: url2,
//data: JSON.stringify(dataa, null, '\t'),
data: {
album: dataa
},
//contentType: "application/json; charset=utf-8", ///////
//dataType:"json",
success: function(dataaz) {
alert("updated");
alert(dataaz.price);
var x2 = JSON.stringify(dataaz, null, '\t');
alert(x2);
},
error: function() {
alert("error in update..");
}
})
}
});
and my api [httpput]action:
[HttpPut]
public async Task<ActionResult<Album>> PutAlbum([FromBody]Album album)
{
_context.Entry(album).State = EntityState.Modified;
await _context.SaveChangesAsync(); return album;
}
when i breakpoint in api action,
I understand that the program does not refer to the action
I searched the internet a lot but I could not find the reason, please help me to solve this problem as soon as possible
It's quite probable that you haven't enabled cross-origin requests. As it is stated here:
Browser security prevents a web page from making AJAX requests to another domain. This
restriction is called the same-origin policy, and prevents a malicious
site from reading sensitive data from another site. However, sometimes
you might want to let other sites call your web API.
So you have to enable first Cors. For that reason, you should go in the WebConfig class of the WebAPI that you want to be called and put the following line anywhere inside the Register method:
config.EnableCors();
Then you should go the controller, in which the PutAlbum is defined and decorate with the following attribute
[EnableCors(origins: "http://mywebclient.azurewebsites.net", headers: "*", methods: "PUT")]
You should replace "http://mywebclient.azurewebsites.net" with the URI of your Web Application, that you want to call your Web API.
UPDATE
The above apply for ASP.NET projects. For ASP.NET Core please have a look at here.
in my asp.net core project, i use following code in ConfigureServices in startup:
services.AddCors(options =>
{
options.AddPolicy(MyAllowSpecificOrigins,
builder =>
{
builder.WithOrigins("*")/*.AllowAnyOrigin()*/.AllowAnyHeader().AllowAnyMethod();
});
});
in we can use the client url instead of * :
.WithOrigins("http://localhost:51111")
and in startup in Configure use :
<pre> app.UseCors();</pre>
I have a post method in my js file which need to send 2 parameters.
var patientData = { 'clinicalRegistryPatient': $scope.patientFile,'emailDetails': $scope.patientFile.emailDetails };
Service.post(Service.API.REGISTER_PATIENT, patientData).then(function success(data) {
toastr.success('changes saved successfully', 'Success');
}
and my api controller (mvc) is like
public IHttpActionResult Post(CPatient Patient,EmailDetails emailDetails=null)
{
}
and in factory
return{
api{
'REGISTER_PATIENT': '/api/patients/add
}
}
post: function (api, data, headers) {
var deferred = $q.defer();
console.log(api);
$http.post(api, data,headers)
.success(function (data) {
deferred.resolve(data);
})
.error(function (err) {
deferred.reject(err);
});
return deferred.promise;
},
but when i am invoking the api, it returns a 500 internal server error and I do not know where the problem is?
Where am I going wrong?
Your api url is wrong; there isnt any action 'Add' in your controller (unless you have attribute routing with action name as 'add' ); POST 'api/patients' should work if "Patients" is your controller name.
Rename 'clinicalRegistryPatient' to the exact param name in the Post method; in this case, it is 'Patient'
I am returning a file from an ASP.NET MVC controller and I want to download it as an attachment using AngularJS.
MVC Controller:
return File(renderedBytes, mimeType);
AngularJS:
function generatePDF(reportRequest) {
var reportController = "Report";
var controllerUrl = ngAppSettings.homeBaseUri + reportController + "/GeneratePDF";
var deferred = $q.defer();
$http({
method: "POST",
url: controllerUrl,
data: reportRequest
}).success(function (data, status, headers, cfg) {
//window.open(controllerUrl, "_self", "");
deferred.resolve(data);
}).error(function (err, status) {
deferred.reject(err);
});
return deferred.promise;
};
I've tried various ways as suggested on the similar questions about this but I'm not getting it.
I've tried this too.
My breakpoints hit without any problems inside the GeneratePDF controller but nothing happens after that. How would I go about this?
EDIT:
I also tried angular file saver but I'm getting an error that the format should be in BLOB. If I can only convert the response to a blob then I think this might be it.
TIA
If your C# Controller endpoint returns a FileContentResult (which it appears that it does), then you shouldn't need to worry about promises. You can simply do the following...
function generatePDF(reportRequest) {
var reportController = "Report";
var controllerUrl = ngAppSettings.homeBaseUri + reportController + "/GeneratePDF";
window.open(controllerUrl, "_blank");
};
I am doing this in one of my apps and it is working as expected. Is there a particular reason you were using the $q service to return a promise?
I inherited some code and I am trying to figure the right url to a webapi controller but my knowledge of mvc web api is lacking.
I have inline script that is making an ajax post like this:
$('#saveNewEducation').on('click', function () {
var educationAdd = {
'educationId': $('#newEducation').val(),
'startDate': $('#newEducationDate').val(),
'identificationId': $('#identificationId').val(),
'educationNote': $('#newEducationNote').val(),
'examinerId': $('#newExaminer').val()
};
$.post('#Url.HttpRouteUrl("DefaultApi", new { controller = "EmployeeApi", educationName = "educationCreate" })', educationAdd)
.done(function (data, textStatus, jqXhr) {
if (jqXhr.status == 200) {
$('#save-education').modal('show');
} else {
$('#fail-save-employee').modal('show');
}
})
.fail(function (jqXhr) {
var education = $("#new-education");
if (jqXhr.status == 409) {
$('#future-save-employee').modal('show');
} else {
if (jqXhr.status == 400) {
clearErrors(education);
var validationErrors = $.parseJSON(jqXhr.responseText);
$.each(validationErrors.ModelState, function (i, ival) {
remoteErrors(education, i, ival);
});
} else {
$('fail-save-employee').modal('show');
}
}
});
I don't like inline script and I have created a seperate js file where I want to make this call from.
I need help with
I need help figuring out the right url to the api controller so that i can use it in the script file.
I tried
Reading this article I tried the following:
$.post('/DefaultApi/EmployeeApi', educationAdd)
This gave me a
404 not found error.
in the inline script the url is like this:
$.post('#Url.HttpRouteUrl("DefaultApi", new { controller = "EmployeeApi", educationName = "educationCreate" })', educationAdd)
WebApiConfig.cs file:
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional });
method I am trying to access in EmployeeApi controller:
public IHttpActionResult EducationPost(EmployeeEducation model, string educationName){}
How can I do this?
Resolving the URL
Generally in MVC applications, you would resolve this by using the Url.Action() helper to resolve the proper URL provided its Controller, Action and RouteValues:
// Supply the Action, Controller and any route values that you need
$.post('#Url.Action("EducationPost","EmployeeApi", new { educationName = "educationCreate"})', function(){
// Do something here
});
However, Web API also features the Url.Link() helper that might be useful as well and works in a similar manner except based on the route itself :
$.post('#Url.Link("DefaultApi", new { controller = "EmployeeApi", action = "EductationPost", educationName = "educationCreate" })', function(){
// Do something here
});
When using External Javascript Files
As you would imagine, these techniques won't work when using external Javascript files. What I generally recommend in these situations is to consider using a data-* attribute in HTML to store the URL and then reference that within your event handler that will trigger the AJAX call :
<button id='call-ajax' data-post-url='#Url.Action(...)' />
<script>
$(function(){
$('#call-ajax').click(function(e){
// Read the attribute and use it
$.post($(this).attr('data-post-url'), function(){
// All done
});
});
});
</script>
You could obviously accomplish this same basic idea through the use of variables or hidden elements, but the same idea basically holds true as far as actually accessing it goes.
Have a look at this answer:
How to send razor created Url to js file
This user offers 3 possible solutions.
global js variable
custom "data-" attribute
hidden input
I have created from wizard Asp Mvc 5 solution with Odata service to EF 6.
I want to send post request and create a record in database
but odata controller ran request, but not map JSON to EF object
what is wrong with my ajax request ?
Odata Method:
// POST: odata/SchoolChildrens
public async Task<IHttpActionResult> Post(SchoolChildrens schoolChildrens)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
db.SchoolChildrensSet.Add(schoolChildrens);
await db.SaveChangesAsync();
return Created(schoolChildrens);
}
JavaScript object Side (not all DB property here no need on client side):
var children = function () {
var self = this;
self.Id = ko.observable(0);
self.FullName = ko.observable();
self.IsPrivilege = ko.observable(false);
self.UseInShortMenu = ko.observable(false);
}
part of code that sent request, both case can't init data
self.addItem = function () {
var newStudent = ko.toJSON(self.newRow());
$.post("/odata/SchoolChildrens", JSON.stringify(newStudent), function (result) {
self.childrenList.push(result.value);
}).fail(function () { console.log("Function : Add SchoolChildrens error"); });
$.ajax({
type: "POST",
url: "/odata/SchoolChildrens",
data: newStudent,
success: function(result) {
self.childrenList.push(result.value);
},
dataType: 'json',
contentType: 'application/json'
});
};
I tried send JSON {schoolChildrens : ko.toJSON(self.newRow())} for map variable name but it also failed.
How I should send post request to odata controller correctly ?
Firstly, check if your request really contains any data (request object from page contains not null or undefined data property)
Second, when you use http methods that can send data in request body (POST, PUT, DELETE), it is necessary to add [FromBody] attribute before object as you want to map as method argument