I want to return just error messages text in web api in ASP.Net Core 2.2,
I use the following code to return values:
if (!ModelState.IsValid)
{
return BadRequest(ModelState.Values);
}
and i get the following response:
[
{
"childNodes": null,
"children": null,
"key": "user.Username",
"subKey": {
"buffer": "user.Username",
"offset": 5,
"length": 8,
"value": "Username",
"hasValue": true
},
"isContainerNode": false,
"rawValue": null,
"attemptedValue": null,
"errors": [
{
"exception": null,
"errorMessage": "Username is required"
}
],
"validationState": 1
}
]
I need just error messages text for response, like this:
{
'data': [
Username is required,
Password is required,
],
'status': 'error'
}
Well, since you're using ASP.NET Core 2.2, you should really be using the ApiController attribute:
[ApiController]
public class FooApiController : ControllerBase
With that, ASP.NET Core actually takes care of bad requests for you automatically, so you don't even need this check in your action at all.
Otherwise, you should use:
ModelState.ToDictionary(x => x.Key, x => x.Value.Errors);
Or if you just want the errors alone, not keyed to the individual properties:
ModelState.SelectMany(x => x.Value.Errors);
Related
I am trying to integrate the Paytm Payment Gateway using API.
I've added .net 4.5 paytm.dll from their git project into my asp.net API project targeting .net framework 4.7
with this I've created checkup using below code:
String merchantKey = "hNIXDAclG8Li#D5X";
Dictionary<string, string> parameters = new Dictionary<string, string>();
parameters.Add("MID", "aTSCQu39976373303724");
parameters.Add("CHANNEL_ID", "WEB");
parameters.Add("INDUSTRY_TYPE_ID", "Retail");
parameters.Add("WEBSITE", "WEBSTAGING");
parameters.Add("CUST_ID", "CUST_01");
parameters.Add("ORDER_ID", "o_1234");
parameters.Add("TXN_AMOUNT", "100.00");
parameters.Add("CALLBACK_URL", "https://securegw.paytm.in/theia/paytmCallback?ORDER_ID=o_1234");
String paytmChecksum = CheckSum.generateCheckSum(merchantKey, parameters);
using generated checksum, I'm trying to create payment like with below API call and JSON object in POSTMAN.
https://securegw-stage.paytm.in/link/create
{
"body": {
"mid": "aTSCQu39976373303724",
"linkType": "INVOICE",
"linkDescription": "Test Payment",
"linkName": "Test",
"sendSms": false,
"sendEmail": false
},
"head": {
"tokenType": "AES",
"signature": "lQWs6oOwK/hEpmfPN9x5GMLUe5pFpcIKdnIYQeDHT5csnul3H1RMsPfCyOQcTXB9FccSsFTbmi5R6S/BUjWCFFcjWxqgdF+jhSFY9uALLqo="
}
}
But it response with the below error
{
"head": {
"version": "v2",
"timestamp": "06/06/2020 17:56:31",
"channelId": null,
"signature": null,
"tokenType": null,
"clientId": null
},
"body": {
"resultInfo": {
"resultStatus": "FAILED",
"resultCode": "5028",
"resultMessage": "Checksum provided is invalid."
}
}
}
Can anybody have solution to this problem?
Thank you in advance. Pardon me for bad grammar.
paytm.CheckSum have below methods only
I am getting below error when calling Docusign API from a C# web api. Able to get the access token but when creating the envelope this error is being received.
Is there any issue with clientUserId because it worked without any hiccups in sandbox. What value do I need to pass in it ? From all the sources, I gather it just indicates that this request is an embedded one. If we have to pass a specific userId in this field how to get it when passing it for envelope creation.
Response:
{
"errorCode": "INVALID_USERID",
"message": "Invalid UserId."
}
Below is the request which we are passing
{
"documents": [
{
"documentId": "1",
"fileExtension": "pdf",
"name": "Trial - OL.pdf"
}
],
"emailSubject": "Docusign Digital Signature",
"recipients": {
"signers": [
{
"clientUserId": "1001",
"email": "XXXX",
"name": "XXXX",
"recipientId": "1",
"routingOrder": "1",
"tabs": {
"signHereTabs": [
{
"anchorIgnoreIfNotPresent": "false",
"anchorString": "XXXX",
"anchorUnits": "inches",
"anchorXOffset": "0",
"anchorYOffset": "-0.25"
}
]
}
}
]
},
"status": "sent"
}
There is no error while retreiving access token
The error is not about clientUser but about the userId of the user.
After you finished Go-Live, the account is different, the user is different, and the URLs for the environments are all different when you migrate from the developer sandbox to the production environment.
If you got a token using JWT, remember that one of the things you used was the userId of the impersonated users.
You cannot use the token generator tokens in production.
Production environment doesn't have a single URL like demo.docusign.net. It can be many different URLs and you have to first figure out what it is before making API calls.
I followed this guide in order to create account linking in my app
https://developers.google.com/actions/identity/google-sign-in#json
I'm able to verify the user's jwt decoder and send back a response that the user is authorised. Then, according to the guide, in the next request, I should get the user's profile payload (user.profile.payload in the json structure) but It's missing from the next request. More than that, I get the tokenId for jwt verification again.
I think that what i miss here is in the possibleIntent object but I'm not sure, as I didn't see any documentation for that, because I work with asp.net server. There are SDKs with documentation for java and nodeJS only
this is the request provided for the sign in the contain the tokenId
{
"user": {
"locale": "en-US",
"lastSeen": "2019-07-11T14:18:10Z",
"idToken": "<tokenId>",
"userVerificationStatus": "VERIFIED"
},
"conversation": {
"conversationId": "ABwppHH9uZfcKj6pS6A6wItKC1dOXuZJ5oFYt2Og7cqrElSQYC9bv-aV7iQ5FDYaJPp-fa7tQNhc2yS0fw3QBu-M",
"type": "ACTIVE",
"conversationToken": "e0e78f40-a207-49c2-9050-50c6ed526c24"
},
"inputs": [
{
"intent": "actions.intent.SIGN_IN",
"rawInputs": [
{
"inputType": "KEYBOARD"
}
],
"arguments": [
{
"name": "SIGN_IN",
"extension": {
"#type": "type.googleapis.com/google.actions.v2.SignInValue",
"status": "OK"
}
},
{
"name": "text"
}
]
}
],
"surface": {
"capabilities": [
{
"name": "actions.capability.SCREEN_OUTPUT"
},
{
"name": "actions.capability.ACCOUNT_LINKING"
},
{
"name": "actions.capability.AUDIO_OUTPUT"
},
{
"name": "actions.capability.MEDIA_RESPONSE_AUDIO"
},
{
"name": "actions.capability.WEB_BROWSER"
}
]
},
"isInSandbox": true,
"requestType": "SIMULATOR"
}
this is the response that i provide after verifying the user.
I tried it with both intents actions.intent.TEXT and actions.intent.SIGN_IN but with no success. the next request is provided with the user.idToken property again instead of the user.profile (that should contain the payload)
{
"conversationToken": "b09d915e-6df9-496d-acde-b76858cd95b4",
"expectUserResponse": true,
"expectedInputs": [
{
"inputPrompt": {
"richInitialPrompt": {
"items": [
{
"simpleResponse": {
"textToSpeech": "Hi",
"displayText": "Hi"
}
}
],
"suggestions": []
}
},
"possibleIntents": [
{
"intent": "actions.intent.TEXT",
"inputValueData": {
"#type": "type.googleapis.com/google.actions.v2.SignInValue",
"status": "OK"
}
}
]
}
]
}
The user.profile attribute you're talking about is something that is provided via the actions-on-google library for JavaScript. It isn't in the JSON that you will receive. But...
You don't need it because the basic profile information (name, email, and Google ID) is encoded in the user.idToken. That string, which will be sent to you for every request, is just a JWT token which you can verify and decode. The profile will be in the "payload" section.
I don't know c#, but https://jwt.io/ contains a list of libraries which can decode the JWT string for you so you can read the "payload".
Keep in mind that you don't need to verify the token each time (although if you do it right, this shouldn't be expensive), but that you can decode it to get the information that you're looking for.
If you don't want to decode it, you can decode it when you first verify it, get the information you need, and store that information in the userStorage string (assuming you don't expect it to change).
I have an api (post method) that takes in a list of transport objects. when I test using swagger, the list comes back with a count of 0 (not null), even though I am sending a List of transports. In below scenario I would assume the count should be 1. Here is a small sample of the Json I am sending.
[{
"type": "",
"attributes": {
"TransportId":"",
"Status": "string",
"Action": "test",
"ActionBy": "string",
"ActionDate": "",
"PackingGroupID": "a713eb0a-5682-4cb5"}]
Here is the api call:
[HttpPost, Route("bulk")]
[ResponseType(typeof(List<Transport>))]
public async Task<IHttpActionResult> SaveTransports([FromBody] List<Transport> transports, string packingGroupId)
{
var resulttransports = await _transportService.SaveTransportsAsync(transports, packingGroupId);
if (resulttransports != null)
ConvertTransportDateToTimezone(ref resulttransports);
return Ok(resulttransports);
}
Bel:ow is an image of result
Try adding one more } at the end. I use JsonFormatter to always test my JSON.
https://jsonformatter.curiousconcept.com/#
[{
"type": "",
"attributes": {
"TransportId":"",
"Status": "string",
"Action": "test",
"ActionBy": "string",
"ActionDate": "",
"PackingGroupID": "a713eb0a-5682-4cb5"}}]
I am using Andy Crum's EmberDataModelMaker.
Having punched in the following two classes
// app/models/server-item.js
export default DS.Model.extend({
hostName: DS.attr('string'),
syncServers: DS.hasMany('string'),
subscribers: DS.hasMany('string'),
mailHost: DS.attr('string'),
mailHostLogin: DS.hasMany('credentials')
});
// app/models/credentials.js
export default DS.Model.extend({
user: DS.attr('string'),
password: DS.attr('string'),
server: DS.belongsTo('serverItem')
});
It's showing the following three different expected JSON formats (a very nice feature btw.):
DS.RESTAdapter
"serverItems": [
{
"id": 1,
"hostName": "foo",
"syncServers": [
<stringids>
],
"subscribers": [
<stringids>
],
"mailHost": "foo",
"mailHostLogin": [
<Credentialsids>
]
}
],
"credentials": [
{
"id": 1,
"user": "foo",
"password": "foo",
"server": <ServerItemid>
}
]
DS.ActiveModelAdapter
"serverItems": [
{
"id": 1,
"host_name": "foo",
"sync_server_ids": [
<stringids>
],
"subscriber_ids": [
<stringids>
],
"mail_host": "foo",
"mail_host_login_ids": [
<Credentialsids>
]
}
],
"credentials": [
{
"id": 1,
"user": "foo",
"password": "foo",
"server_id": <ServerItemid>
}
]
DS.JSONAPIAdapter
{
"data": {
"type": "server-items",
"id": "1",
"attributes": {
"HostName": "foo",
"MailHost": "foo",
},
"relationships": {
"SyncServers": {
"data": {
"type": "SyncServers",
"id": <SyncServersid>
}
},
"Subscribers": {
"data": {
"type": "Subscribers",
"id": <Subscribersid>
}
},
"MailHostLogin": {
"data": {
"type": "MailHostLogin",
"id": <MailHostLoginid>
}
}
},
"included": [
{
<sideloadedrelationships>
]
}
}
}
{
"data": {
"type": "credentials",
"id": "1",
"attributes": {
"User": "foo",
"Password": "foo",
},
"relationships": {
"Server": {
"data": {
"type": "Server",
"id": <Serverid>
}
}
},
"included": [
{
<sideloadedrelationships>
]
}
}
}
I am going to implement (or rather change) some WebServices on the Server side (using C#, ASP.NET Web API). Currently, the WebService already creates a result that is pretty similar to the format expected with DS.RESTAdapter - obviously, it would be ideal if I could use it without compromising the Data Integrity - can I?
If yes, would it empower Ember Data to send all the requests necessary to maintain the data consistency on the server? Meaning, would the client send a DELETE request to the server not only for the ServerItem but also for the Credentials item that is referenced via the mailHostLogin property when the user wants to delete a ServerItem?
If not: are both of the other two adapters fulfilling the above mentioned consistency requirement? Which of the other two should I implement - any experiences/recommendations out there?
You should choose whichever Adapter closest fits your API data structure as a basis(sounds like DS.RESTAdapter in this case). You can extend the adapters and serializers that are a closest fit to make any necessary adjustments(this can be done both application wide or on a per model basis).
However, I don't think that the Ember Data model relationships(i.e. belongsTo and hasMany) are binding in such a way that will automatically result in the "data consistency" you are looking for. If your application requirements are to delete all associated Credentials records when a ServerItem is deleted, I would recommend doing that server side when handling the DELETE ServerItem API request. That would result in better performance(1 HTTP call instead of 2 or N depending if credentials can be deleted in bulk) and be much less error prone due to potential network or other failure of calls to delete Credentials after a ServerItem is deleted.
After a successful ServerItem delete, you could loop through it's credentials and unload the records from the client side store to keep it in sync with the new state on the server. Something like:
serverItemCredentials.forEach(function(id) {
if (this.store.recordIsLoaded('credential', id)) {
this.store.unloadRecord(this.store.peekRecord('credential', id));
}
});