I currently have an issue with a webapi call. I want to download and open a logfile with my ApiController.
I use a javascript function to post a filename to my controller.
Here is a helper function to post the parameter (answer from dystroy):
How to replace window.open(...) with a POST
Now when I use a simple string as parameter in my controller I can’t get the parameter, it is always null.
public HttpResponseMessage PostDownloadLogFile([FromBody]string psFileName)
{
//psFileName is always null
But if I use HttpReqeustMessage as parameter and read the form data from my request it is no problem and it works.
public HttpResponseMessage PostDownloadLogFile(HttpRequestMessage poRequest)
{
var loFormData = poRequest.Content.ReadAsFormDataAsync().Result;
string psFileName = loFormData["psFileName"]; //psFileName is set correct
Is there a solution to get the parameter with a simple parameter in my controller?
Update
This is my javascript helper function:
var loOpenWindow = function (psMethode, psUrl, poData, psTarget) {
var loForm = document.createElement("form");
loForm.action = psUrl;
loForm.method = psMethode;
loForm.target = psTarget || "_self";
if (poData) {
for (var lsKey in poData) {
var loInput = document.createElement("textarea");
loInput.name = lsKey;
loInput.value = typeof poData[lsKey] === "object" ? JSON.stringify(poData[lsKey]) : poData[lsKey];
loForm.appendChild(loInput);
}
}
loForm.style.display = "none";
document.body.appendChild(loForm);
loForm.submit();
};
Call it:
helper.openWindow("POST", apiRoutes.URLS.ApiPostDownloadLogFile, { "psFilename": $scope.data.showLogEntry.FullName });
There should be no problem from the client side code, because the controller methode with HttpReqeustMessage works without problems.
Here is the browser request:
Probably the problem is in your client code sending the data.
[FromBody] parameters must be encoded as =value
then, this does not work:
// Value will be null.
$.post('api/values', value);
// Value will be null.
$.post('api/values', { key: value });
But this work:
$.post('api/values', "=" + value);
Try to change your client code to send just =/path/to/your/file in the body.
Reference: http://encosia.com/using-jquery-to-post-frombody-parameters-to-web-api/
Ok I found a solution.
If I use a class as parameter and a property with the given name, it seems to work.
public class Param
{
public string psFileName { get; set; }
}
And
public HttpResponseMessage PostDownloadLogFile(Param poParam)
{
string psFileName = poParam.psFileName; //psFileName is set correct
This is not really a simple parameter but I can live with this solution.
Related
Here is my code. I'm trying to display a list when a property is selected from a combobox. I'm getting the list from backend, but I get this error whenever I click the display button. Even though, the method is a GET method. What could be the problem?
TS:
filter() {
this._stockService
.getWarehouseTransferReport()
.subscribe((response: any) => {
this.dataSource = new MatTableDataSource(response);
this.dataSource.paginator = this.paginator;
this.dataSource.sort = this.sort;
this.dataSource.filterPredicate = (data, filter) =>
this.filterPredicate(data, filter);
});
}
filterPredicate(data: IWarehouseTransferItem, filter: string) {
let searchText = data.Reference;
if (data.Reference) {
searchText += (data.Reference as any).toLocaleLowerCase("tr");
}
if (data.DeliveryNote) {
searchText += (data.DeliveryNote as any).toLocaleLowerCase("tr");
}
if (data.StockIntegrationCode ) {
searchText += (data.StockIntegrationCode as any).toLocaleLowerCase("tr");
}
if (data.Product.ProductName) {
searchText += (data.Product.ProductName as any).toLocaleLowerCase("tr");
}
return searchText.indexOf(filter) >= 0;
}
Service TS:
getWarehouseTransferReport(): Observable<IWarehouseTransferItem[]> {
return this._http.get("Stock/GetWarehouseTransferReport");
}
Backend C#:
/// <summary>
/// TRANSFER REPORT
/// </summary>
/// <param name="producdId"></param>
/// <returns></returns>
[HttpGet]
public List<DtoWarehouseTransferItem> GetWarehouseTransferReport(int producdId)
{
return WarehouseSpProvider.GetWarehouseTransferReport(producdId);
}
}
It probably means that server know the method but the target source is not supported. Here is the reference Mozilla link.
So basically it is not Angular Http client problem to be precise.
Reference link which shows many details on 405 status code problem. Link
Your C# Backend code requires a parameter int productId but I think you are not passing any parameter that's why it is now being called.
May be you are passing wrong object or object mismatches the value.
may be datatype issue or parameter count issue and your API needs
proper object and value.
I've been given a script function and would like to partially translate it to C# in a Blazor app
<script>
function pay() {
var token = document.getElementById('token').value;
var card = document.getElementById('card').value;
var exp = document.getElementById('exp').value;
var cvv = document.getElementById('cvv').value;
var paymentData = {
ssl_txn_auth_token: token,
ssl_card_number: card,
ssl_exp_date: exp ,
ssl_cvv2cvc2: cvv
};
ConvergeEmbeddedPayment.pay(paymentData);
return false;
}
</script>
I want to call the script (that is inside the script above)
ConvergeEmbeddedPayment.pay(paymentData);
Directly from c# . Like so
await JsRuntime.InvokeVoidAsync("ConvergeEmbeddedPayment.pay", paymentData);
There is some good information here:
https://learn.microsoft.com/en-us/aspnet/core/blazor/call-javascript-from-dotnet?view=aspnetcore-3.1
But it stops short of helping me.
What kind of variable should I pass in the paymentData parameter? And how should I pass it?
I've tried var , object and string and also tried JsonSerializer.Serialize( ); but no luck
Based on suggestion from #BurningKarl I tried Dictionary and object[] but
I get an error saying the content is missing or "Expected BEGIN_OBJECT but was STRING "
Looks like you have to create your own c# class that mimics the payment data object in your Javascript.
Something like this
public class PaymentData
{
public string ssl_txn_auth_token {get; set;}
public string ssl_card_number{get; set;}
public string ssl_exp_date{get; set;}
public string ssl_cvv2cvc2{get; set;}
}
Then you have to create an instance of this class and pass it to InvokeVoidAsync as an argument.
var data = new PaymentData ()
{
ssl_txn_auth_token = "authtokenvalue",// you have to get it from control
ssl_card_number = "card number",
ssl_exp_date: "date", // probably it should be daytime or similar
ssl_cvv2cvc2 = "111"
}
await JsRuntime.InvokeVoidAsync("ConvergeEmbeddedPayment.pay", data);
in my application I have my JS file that reads some info filled in the html page. What I want to do now I passing these info to my controller. So in my script I have:
function addNewEmployee() {
var newEmployeeName = document.getElementById("newEmployeeName").value;
var newEmployeeSurname = document.getElementById("newEmployeeSurname").value;
var newEmployeeDateOfBirth = document.getElementById("newEmployeeDateOfBirth").value;
var newEmployeeRole = document.getElementById("newEmployeeRole").value;
var newEmployeeEmail = document.getElementById("newEmployeeEmail").value;
var newEmployee = {
name : newEmployeeName,
surname: newEmployeeSurname,
dateOfBirth: newEmployeeDateOfBirth,
role: newEmployeeRole,
email : newEmployeeEmail
}
$.post("api/addemployees", {'newEmployee': newEmployee}, function(result) {
});
}
I would like to know if passing an object in this way is correct and then how can I receive it on my controller side:
[HttpPost]
[Route("api/addemployees")]
public bool AddEmployee (Object newEmployee)
{
return true;
}
Unfortunately by debugging on the controller side I realized that this way is not correct because nothing arrives. How can I solve this? Thanks in advance.
Just pass the object like
$.post("api/addemployees", JSON.stringify(newEmployee), function(){
})
It is such that I must have sent some content from my controller over to Angularjs which shall come forth with words such as only L in themselves or E, so it goes in other words, of words where it like just let the words sign which has the single letter.
There is no fault forward by the console and what I believe is the problem is that it does not specify any value to the side.
i have try its here:
A circular reference was detected while serializing an object of type 'SubSonic.Schema .DatabaseColumn'.
Load.js
var app = angular.module('WordSpreads',[]);
app.controller('WordSpreadsListValue', function ($scope, $http) {
$http(
{
method: 'GET',
url: '../Profile/MWordSpreads'
}).success(function (response) {
$scope.entries = data.List;;
});
console.log("TEST");//It does not appear in the console log.
});
Controller:
[HttpGet]
public JsonResult MWordSpreads()
{
WordsSpreadsListValue model = new WordsSpreadsListValue();
var db = HelperToTables.DbValue;
model.List = db.WordSpreads.ToList();
return Json(model.List, JsonRequestBehavior.AllowGet);
}
Model:
public class WordsSpreadsListValue
{
public List<WordSpread> List { get; set; }
}
Error giv me:
A circular reference was detected while serializing an object of type
'xxSitename.Models.LinqDatabase.WordSpread'
UPDATE:
model.List = db.WordSpreads.Select(x => new {
Name = x.name,
TextValue = x.text.ToString()
}).ToList();
ERROR :
Cannot implicitly convert type
'System.Collections.Generic.List<>' to
'System.Collections.Generic.List' MVCOrdklar2015
.
model.List = db.WordSpreads.Select(x => new { Prop1 = x.1, Prop2 = x.2}).ToList();
You are having trouble serializing model.List, the Json serialize is barfing on serializing model.List. If you make it a new object without navigation properties you will be fine.
In my experience it has to do with the navigation properties, I dont fully understand what it is. But, once you remove the navigation properties from the equation it will work.
I want to save some var to my session, and when i make the request with ajax this dont work.
This is the service:
function HuntService( $http ) {
this.hunts= {
draws : null,
hunters: null
};
this.saveToSession = function( hunts) {
var hunts = this.hunts;
return $http.post('saveToSession', {
hunts: hunts
});
};
}
HuntService.$inject = ['$http'];
module.exports = HuntService;
and the controller:
class HuntController extends \BaseController {
public function saveItems() {
Session::put('hunts', Input::get('hunts'));
return Response::json(array('saved' => true), 200);
}
public function destroy($id) {
Session::forget('hunts');
}
public function getHunts() {
return Session::get('hunts') // dont exits
}
}
And when im trying as test to get to this with regular request and no ajax its working.
The problem is here:
var hunts = this.hunts;
Here, this.hunts does not exist.
NOTE:
Use Inspect Element/Debug tool for inspecting the request & check whether it is sending any value for hunts attribute in post method or just blank. The laravel part looks ok.