How to pinpoint serialisation errors on Web API endpoints? - c#

At times I have an endpoint on my web api:
[HttpPost]
public async Task Foo([FromForm] int[] a, [FromForm] int b, ...) {
await Task.Delay(1000);
}
When calling this from the client side using axios:
var formData = new FormData();
formData.append('a', this.selected.map(n => n.id));
formData.append('b', this.id);
await this.axios.post('/api/v1/foo', formData);
I get a 400 error. Which states in no way of which field caused the issue. Is there a way of finding out other than trial and error?
POST https://localhost:5001/api/v1/foo 400 (Bad Request)

For Asp.Net Core Api, if you check the web browser network tab, you will see below which already return the expected error response.
{
"errors": {
"a": [
"The value '1,2,3' is not valid."
]
},
"title": "One or more validation errors occurred.",
"status": 400,
"traceId": "8000001e-0004-fe00-b63f-84710c7967bb"
}
If you want to capture the errors by axios, you could try
var formData = new FormData();
formData.append('a', "1,2,3");
formData.append('b', "1");
axios.post('/api/values/Foo', formData)
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(JSON.stringify(error.response.data.errors));
});

Related

C# Firestore API POST - Cannot find field

I have hit a bit of a brick wall here. I am working in client side c# code and using the firestore API. I cannot post a document (with data) in. I am able to create a document by removing the line ".AddJsonBody(testdata)" below.
CODE
string url = "https://firestore.googleapis.com/v1/projects/<MYPROJECT>/databases/(default)/documents/Users";
var client = new RestClient(url);
string testdata = "{\"foo\":\"bar\"}";
var request = new RestRequest()
.AddJsonBody(testdata);
var response = await client.ExecutePostAsync(request);
ERROR
{
"error": {
"code": 400,
"message": "Invalid JSON payload received. Unknown name "foo" at 'document': Cannot find field.",
"status": "INVALID_ARGUMENT",
"details": [
{
"#type": "type.googleapis.com/google.rpc.BadRequest",
"fieldViolations": [
{
"field": "document",
"description": "Invalid JSON payload received. Unknown name "foo" at 'document': Cannot find field."
}
]
}
]
}
}
I have tried using document:commit. I have tried various different methods of parsing the data, all keep getting similar errors.

Not able to bind data to datatable in ASP.NET MVC

Below is my code from view from my ASP.NET MVC project. I am using datatable to create a table. I am fetching data from a Web API. Data is being returned but while binding I get the error shown here. I tried deleting a lot of code which had buttons. Now I just have code for simply binding it.
datatables warning: table id=patients - ajax error. for more information about this error, please see http://datatables.net/tn/7
jQuery code :
$(document).ready(function () {
debugger;
var table = $("#patients").DataTable({
ajax: {
url: "/api/patients",
dataSrc: ""
},
columns: [
{
data: "First_Name"
},
{
data: "phoneNumber",
render: function (data) {
debugger;
return data.toString().replace(
/(\d\d\d)(\d\d\d)(\d\d\d\d)/g, '$1-$2-$3');
}
},
{
data: "Address"
},
]
});
});
API code from controller:
public IHttpActionResult GetPatients()
{
var patientDto = getdata();
return Ok(patientDto);
}
public IEnumerable<Patient_Response> getdata()
{
IEnumerable<Patient_Response> students = null;
using (var client = new HttpClient())
{
client.DefaultRequestHeaders.Add("Authorization", "Bearer 0f6af107-6ad2-4665-ad24-f09402d50082");
client.BaseAddress = new Uri("http://localhost:6600/api/");
// HTTP GET
var responseTask = client.GetAsync("patients");
responseTask.Wait();
var result = responseTask.Result;
if (result.IsSuccessStatusCode)
{
var readTask = result.Content.ReadAsAsync<IList<Patient_Response>>();
readTask.Wait();
students = readTask.Result;
}
else //web api sent error response
{
// log response status here..
students = Enumerable.Empty<Patient_Response>();
ModelState.AddModelError(string.Empty, "Server error. Please contact administrator.");
}
}
return students;
}
What is wrong? I am not able to figure out.
Did you read the documentation: https://datatables.net/manual/tech-notes/7
This occurs when jQuery falls into its error callback handler (this callback built into DataTables), which will typically occur when the server responds with anything other than a 2xx HTTP status code.
That means that your call go the controller, failed to bring any data.
You can use the following code to see what went wrong:
$.fn.dataTable.ext.errMode = 'none';
$('#patients')
.on( 'error.dt', function ( e, settings, techNote, message ) {
alert( 'An error has been reported by DataTables: ', message );
} )
.DataTable();

Call BOT listening URL from Ajax function Web method

I created an web application with submit button. When the user clicks on this button, there will be Ajax call invoked to communicate the BOT. I used following code for Ajax function
<script>
$(document).ready(function () {
$("#btnSend").click(function (e) {
$.ajax({
type: "POST",
url: "GroupChat.aspx/GetData",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (response) {
alert("success!");
},
error: function (response) {
alert(response.d);
}
});
return false;
});
});
</script>
And I used following code to communicate BOT from the web method
[WebMethod]
public static async Task GetData()
{
Task<TokenResponse> response = GetTokenAsync();
response.Wait();
string token = response.Result.access_token;
List<BOTConstants> lstConstants = new List<BOTConstants>();
lstConstants.Add(new BOTConstants
{
text = "test message",
channelId = "webApp",
serviceUrl = "https://smba.trafficmanager.net/in/",
textFormat = "plain",
type = "message"
});
string json = (new JavaScriptSerializer()).Serialize(lstConstants);
var data = new StringContent(json, Encoding.UTF8, "application/json");
using (var client = new HttpClient())
{
//client.BaseAddress = new Uri("https://mybot.azurewebsites.net");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var result = await client.PostAsync("https://mybot.azurewebsites.net/api/messages", data).ConfigureAwait(false);
string resultContent = await result.Content.ReadAsStringAsync();
Console.WriteLine(resultContent);
}
}
But, var result = await client.PostAsync("https://mybot.azurewebsites.net/api/messages", data).ConfigureAwait(false); is always returns Bad request.
Can anybody help me on this to resolve this issue, Please correct me if any mistakes in the above code.
You should use the direct line API instead of posting directly to your "api/messages" endpoint.
Based on Microsoft documentation, below should be the steps. For the same end-user, you should cache the token and conversation id, so your conversation can continue properly in a multi-turn dialog.
Start a conversation.
POST https://directline.botframework.com/v3/directline/conversations
Authorization: Bearer SECRET
//Response
{
"conversationId": "abc123",
"token": "RCurR_XV9ZA.cwA.BKA.iaJrC8xpy8qbOF5xnR2vtCX7CZj0LdjAPGfiCpg4Fv0y8qbOF5xPGfiCpg4Fv0y8qqbOF5x8qbOF5xn",
"expires_in": 1800,
"streamUrl": "https://directline.botframework.com/v3/directline/conversations/abc123/stream?t=RCurR_XV9ZA.cwA..."
}
After you get the conversation id e.g. "abc123", you can start posting your message to this conversation.
POST https://directline.botframework.com/v3/directline/conversations/abc123/activities
Authorization: Bearer RCurR_XV9ZA.cwA.BKA.iaJrC8xpy8qbOF5xnR2vtCX7CZj0LdjAPGfiCpg4Fv0
Content-Type: application/json
[other headers]
//Request body
{
"locale": "en-EN",
"type": "message",
"from": {
"id": "user1"
},
"text": "hello"
}

How do I solve ok: false response with Angular 5 and .NET Core?

There is simple method returning Ok:
[HttpGet("request_name")]
public IActionResult request_name()
{
using (var db = new WordContext())
{
return Ok("This is ok response string");
}
}
And simple request in ngx:
request_name() {
return this.http
.get<string>(`${this.apiUrl}/request_name`);
}.subscribe(x => {
});
I can see code 200 "This is ok response string" in chrome, but there is error message in chrome console:
ERROR HttpErrorResponse {headers: HttpHeaders, status: 200,
statusText: "OK", url:
"http://localhost:4200/main/name/request_name", ok: false, …}
What does it mean and how do I solve it?
Updated
The error message:
error:
error: SyntaxError: Unexpected token T in JSON at position 0 at JSON.parse (<anonymous>) at XMLHttpRequest.onLoad (http://localhost:5010/vendor.js:7457:51) at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (http://localhost:5010/polyfills.js:2743:31) at Object.onInvokeTask (http://localhost:5010/vendor.js:36915:33) at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (http://localhost:5010/polyfills.js:2742:36) at Zone.push../node_modules/zone.js/dist/zone.js.Zone.runTask (http://localhost:5010/polyfills.js:2510:47) at ZoneTask.push../node_modules/zone.js/dist/zone.js.ZoneTask.invokeTask [as invoke] (http://localhost:5010/polyfills.js:2818:34) at invokeTask (http://localhost:5010/polyfills.js:3862:14) at XMLHttpRequest.globalZoneAwareCallback (http://localhost:5010/polyfills.js:3888:17)
message: "Unexpected token T in JSON at position 0"
stack: "SyntaxError: Unexpected token T in JSON at position 0↵ at JSON.parse (<anonymous>)↵ at XMLHttpRequest.onLoad (http://localhost:5010/vendor.js:7457:51)↵ at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (http://localhost:5010/polyfills.js:2743:31)↵ at Object.onInvokeTask (http://localhost:5010/vendor.js:36915:33)↵ at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (http://localhost:5010/polyfills.js:2742:36)↵ at Zone.push../node_modules/zone.js/dist/zone.js.Zone.runTask (http://localhost:5010/polyfills.js:2510:47)↵ at ZoneTask.push../node_modules/zone.js/dist/zone.js.ZoneTask.invokeTask [as invoke] (http://localhost:5010/polyfills.js:2818:34)↵ at invokeTask (http://localhost:5010/polyfills.js:3862:14)↵ at XMLHttpRequest.globalZoneAwareCallback (http://localhost:5010/polyfills.js:3888:17)"
__proto__: Error
text: "This is ok response string"
__proto__: Object
headers: HttpHeaders
lazyInit: ƒ ()
lazyUpdate: null
normalizedNames: Map(0) {}
__proto__: Object
message: "Http failure during parsing for http://localhost:5005/main/word/request_name"
name: "HttpErrorResponse"
ok: false
status: 200
statusText: "OK"
url: "http://localhost:5005/main/word/request_name"
If your response type is not a JSON it will just pass the response to the error
Try something like this
request_name() {
return this.http
.get<string>(`${this.apiUrl}/request_name`, {responseType: 'text'});
}.subscribe(x => {
});
Whereas don't use subscribe use pipe operator and tap to read the response - hope i think you are using HttpClient in angular
return this.http
.get<string>(`${this.apiUrl}/request_name`, {responseType: 'text'});
}.pipe(tap(res => {
console.log(res);
}));

Android in-app-purchase validation on backend

I'm using validation of user's in app purchase with google API:
Purchases.products: get
https://developers.google.com/android-publisher/api-ref/purchases/products/get
In C# on the backend I create HttpWebRequest with this url:
var url = string.Format("https://www.googleapis.com/androidpublisher/v2/applications/{0}/purchases/products/{1}/tokens/{2}", packageName, androidProductId, token);
var request = HttpWebRequest.Create(url);
request.Method = "GET";
The parameters packageName, productId and token, were set correctly.
After I send the request, google answers me with the next JSON object:
{
"error": {
"errors": [
{
"domain": "global",
"reason": "required",
"message": "Login Required",
"locationType": "header",
"location": "Authorization"
}
],
"code": 401,
"message": "Login Required"
}
}
So, the problem is about authorization my backend server. How could this be fixed?
I use IAP for authorization on backend server. Please read this article(russian language).

Categories

Resources