I want to make a post to an API, and the link I'm using to make the post call has some URL parameters.
Link to make post: http://someservice/api/v1/requests?input_data=encoded_data
The parameter (input_data) is a JSON that needs to be encoded before.
When I use this link to encode the below JSON, and I add the encoded result to the URL and make the post with Postman, it works just fine.
{
"request":{
"requester":{
"email_id":"**phx#phx.com**"
},
"subject":"**subject**",
"description":"**description something**"
}
}
This is what I have in my method:
[HttpPost]
[Route("projectRequest")]
[Consumes("multipart/form-data")]
public IActionResult CreateConfig([FromForm] ConfigInputModel model) {
try {
var json =
"{" +
"\"request\":{ " +
"\"requester\":{ " +
"\"email_id\" : \" " + model.Requester + " \" " +
"}," +
"\"subject\":\" " + model.Subject + " \" \", " +
"\"description\":\" " + model.Description + " \" \" " +
"}" +
"}";
HttpClient httpClient = new HttpClient();
Encoding utf16le = new UnicodeEncoding(bigEndian: false, byteOrderMark: true,throwOnInvalidBytes: true);
HttpContent content = new StringContent(Newtonsoft.Json.JsonConvert.SerializeObject(json));
var postResponse = httpClient.PostAsync("http://someservice/api/v1/requests?input_data=" +
System.Web.HttpUtility.UrlEncode(json), content);
return Ok(postResponse.Result);
} catch (Exception e) {
return NotFound();
}
}
My question is how can I encode the JSON variable, because I'm getting
"Unable to parse the JSON"
response from the API. I suspect the escape characters in the JSON string I have are causing it, but can't figure it out for quite a while. Thanks.
Instead of writing JSON as a string, would suggest setting the data as object with POCO class or anonymous type. And next, serialize it to a JSON string.
Benefit: Avoid JSON syntax errors.
anonymous type
var json = new {
request = new {
requester = new {
email_id = model.Requester
}
},
subject = model.Subject,
description = model.Description
};
Console.WriteLine(JsonConvert.SerializeObject(json));
Sample program
Output
{"request":{"requester":{"email_id":"Requester"}},"subject":"Subject","description":"Description"}
I test your code in my side and when I using JObject jsonObj = JObject.Parse(json); to transfer your json string, I got the error about request.subject and request.description,
then I found you made a mistake in this place, you should remove what I marked in the screenshot below.
Related
I'm trying to send a file using zoom api, and I have a OAuth server-to-server authentication with /chat_message:write:admin in my app scope and I have tested simple message without problems. I already have a token, my ID and my recipient's ID.
My program runs and returns error 405 method not allowed.
I choose to send label.pdf file.
Zoom documentation page is: link to zoom api send document
private static final String API_ENDPOINT = "https://api.zoom.us/v2/chat/users/";
// Create API URL
URL url = new URL(API_ENDPOINT + userId + "/messages/files");
// Open connection and set request properties
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setRequestProperty("Authorization", "Bearer " + token);
conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=boundary");
byte[] pdfData = Files.readAllBytes(new File(filePath).toPath());
String boundary = "boundary";
String delimiter = "--" + boundary + "\r\n";
StringBuilder builder = new StringBuilder();
builder.append(delimiter);
builder.append("Content-Disposition: form-data; name=\"to_contact\"\r\n\r\n");
builder.append(toContact+"\r\n");
builder.append(delimiter);
builder.append("Content-Disposition: form-data; name=\"files\"; filename=\"label\"\r\n");
builder.append("Content-Type: application/pdf\r\n");
builder.append("\r\n");
builder.append(new String(pdfData, "ISO-8859-1"));
builder.append("\r\n");
builder.append("--" + boundary + "--");
conn.setDoOutput(true);
String multipartData = builder.toString();
System.out.println(multipartData);
conn.getOutputStream().write(multipartData.getBytes("UTF-8"));
// Send request and get response code and message
conn.connect();
int responseCode = conn.getResponseCode();
String responseMessage = conn.getResponseMessage();
// Check if response is successful
if (Arrays.asList(RESPONSE_CODE).contains(Integer.toString(responseCode))) {
System.out.println("File sent successfully!");
System.out.println("Response code: " + responseCode);
System.out.println("Response message: " + responseMessage);
} else {
System.out.println("Error sending file:");
System.out.println("Response code: " + responseCode);
System.out.println("Response message: " + responseMessage);
}
// Close connection
conn.disconnect();
Can anyone suggest me what's wrong?
So I am trying to do the Get method call to retrieve data from api server.The problem I am getting is that in Unity Editor, Both Get and Post method works perfectly fine, but in the webgl build only post method works whereas Get method returns 500 as error code and webrequest.error as Connection Error.Is there any workaround for this.
public IEnumerator GetPlayerData()
{
Debug.Log("This is Working");
string url = "https:my api";
Authorization playerData = new Authorization();
playerData.walletaddress = PlayerPrefs.GetString("Account");
playerData.table = "userdata";
string jsonStringTrial = JsonUtility.ToJson(playerData);
using (UnityWebRequest webRequest = UnityWebRequest.Get(url))
{
Debug.Log("This is also Working");
webRequest.method = UnityWebRequest.kHttpVerbGET;;
webRequest.SetRequestHeader("Content-Type", "application/json");
webRequest.SetRequestHeader("Accept", "application/json");
webRequest.uploadHandler = new UploadHandlerRaw(System.Text.Encoding.UTF8.GetBytes(jsonStringTrial));
yield return webRequest.SendWebRequest();
Debug.Log(jsonStringTrial);
Debug.Log("This was not Working");
Debug.Log("Data we Received : " + webRequest.downloadHandler.text); // this is always emtpy in webgl but works in editor
if(webRequest.result == UnityWebRequest.Result.ProtocolError)
{
Debug.Log(webRequest.result);
Debug.Log("Protocol Error");
Debug.Log(webRequest.error);
Debug.Log("Error Code" + webRequest.responseCode);
}
if (webRequest.result == UnityWebRequest.Result.DataProcessingError)
{
Debug.Log(webRequest.result);
Debug.Log("DataProcessingError");
Debug.Log(webRequest.error);
Debug.Log("Error Code" + webRequest.responseCode);
}
if (webRequest.result == UnityWebRequest.Result.ConnectionError)
{
Debug.Log(webRequest.result);
Debug.Log(webRequest.error);
Debug.Log("ConnectionError");
Debug.Log("Error Code" + webRequest.responseCode);
}
if (webRequest.result == UnityWebRequest.Result.Success)
{
Debug.Log(webRequest.result);
Debug.Log("Error Code" + webRequest.responseCode);
}
if (webRequest.downloadHandler.text == "{}" || string.IsNullOrEmpty(webRequest.downloadHandler.text))
{
MainMenuHandler.Instance.OpenPanel(MainMenuHandler.Instance.playerLoginPanel);
StartCoroutine(nameof(DisplayMessage));
messageField.text = "Creating Player";
}
else
{
var newData = JsonConvert.DeserializeObject<Root>(webRequest.downloadHandler.text);
PlayerPrefs.SetString(playerNamePrefKey, newData.Item.name);
PlayerPrefs.SetInt("PlayerAvatar", newData.Item.character);
StartCoroutine(GetUserBalance());
yield return new WaitForSeconds(2f);
//NetworkManager.Instance.Connect();
StartCoroutine(nameof(DisplayMessage));
messageField.text = "Getting Data";
}
}
}
Browser Console Log
The "correct" way to fix this issue is to have a look why the server is returnig a 500 Error. 500 errors mean that the problem is something on the server and not on the (Unity-)Client.
So it's not really a Unity problem but a Server problem.
The authentication process is not working now.(It was working earlier). By following the documentation I'm trying to get the access token from a refresh token. I successfully can get a access token. But it's not valid. I'm setting it as Bearer and send it in my GET request and it returns the following JSON
{"error":{"code":"accessDenied","message":"Access Denied"}}
Here is the code sample
String messageBody = "client_id=" + "9b1a6dbb-7e1f-41b5-b448-9f328169411e" + "&redirect_uri=" + returnURL + "&client_secret={cleindsecret}
+ "&refresh_token={refreshtoken}&grant_type=refresh_token";
RequestBody oAuthCodeRedeemBody = RequestBody.create(MediaType.parse("application/x-www-form-urlencoded"),
messageBody);
Request request = new Request.Builder().url("https://login.live.com/oauth20_token.srf")
.post(oAuthCodeRedeemBody).build();
String responseBody = null;
OkHttpClient client = new OkHttpClient();
client.setFollowRedirects(false);
Response response;
String accessToken = null;
try {
response = client.newCall(request).execute();
responseBody = response.body().string();
resp = (JSONObject) jsonParser.parse(responseBody);
} catch (IOException | ParseException e) {
e.printStackTrace();
}
accessToken = (String) resp.get("access_token");
I'm getting a Access Token here. But I can't use it to do any work.
Request request2 = new Request.Builder().url("https://api.onedrive.com/v1.0/drive/items/1ED8983F38E94F01!107/children").header("Authorization", "Bearer " + accessToken).get().build();
The response for the above code is returned as
{"error":{"code":"accessDenied","message":"Access Denied"}}
What is the reason here. Is the API returning me a invalid access token or is something wrong in my code?
Folks,
I'm using Apache CXF (JAX-RS)'s LoggingInInterceptor and LoggingOutInterceptor to log the request and response objects to my web service and also to log the response time.
For this, I have extended both these classes and done relevant configuration in the appropriate XML files. Doing this, I was able to log the request and response object.
However, I also want to log the request URL in both these interceptors. I was able to get the HttpServletRequest object (Inside the LoggingInInterceptor) using the following:
HttpServletRequest request = (HttpServletRequest)message.get(AbstractHTTPDestination.HTTP_REQUEST);
Then, from the request object I was able to get the request URL (REST URL in my case). I was however, not able to get the request object in the LoggingOutInterceptor using this code (or by any other means).
Here is a summary of the issue:
I need to access the reqeuest URI inside the LoggingOutInterceptor (using HttpServletRequest object perhaps?).
Would appreciate any help on this.
Update: Adding the interceptor code.
public class StorefrontRestInboundInterceptor extends LoggingInInterceptor {
/**
* constructor.
*/
public StorefrontRestInboundInterceptor() {
super();
}
#Override
public void handleMessage(final Message message) throws Fault {
HttpServletRequest httpRequest = (HttpServletRequest) message.get(AbstractHTTPDestination.HTTP_REQUEST);
if (isLoggingRequired()) {
String requestUrl = (String) message.getExchange().get("requestUrl");
Date requestTime = timeService.getCurrentTime();
LOG.info("Performance Monitor started for session id:" + customerSession.getGuid());
LOG.info(httpRequest.getRequestURI() + " Start time for SessionID " + customerSession.getGuid() + ": "
+ requestTime.toString());
}
try {
InputStream inputStream = message.getContent(InputStream.class);
CachedOutputStream outputStream = new CachedOutputStream();
IOUtils.copy(inputStream, outputStream);
outputStream.flush();
message.setContent(InputStream.class, outputStream.getInputStream());
LOG.info("Request object for " + httpRequest.getRequestURI() + " :" + outputStream.getInputStream());
inputStream.close();
outputStream.close();
} catch (Exception ex) {
LOG.info("Error occured reading the input stream for " + httpRequest.getRequestURI());
}
}
public class StorefrontRestOutboundInterceptor extends LoggingOutInterceptor {
/**
* logger implementation.
*/
protected static final Logger LOG = Logger.getLogger(StorefrontRestOutboundInterceptor.class);
/**
* constructor.
*/
public StorefrontRestOutboundInterceptor() {
super(Phase.PRE_STREAM);
}
#Override
public void handleMessage(final Message message) throws Fault {
if (isLoggingRequired()) {
LOG.info(requestUrl + " End time for SessionID " + customerGuid + ": " + (timeService.getCurrentTime().getTime() - requestTime)
+ " milliseconds taken.");
LOG.info("Performance Monitor ends for session id:" + customerGuid);
}
OutputStream out = message.getContent(OutputStream.class);
final CacheAndWriteOutputStream newOut = new CacheAndWriteOutputStream(out);
message.setContent(OutputStream.class, newOut);
newOut.registerCallback(new LoggingCallback(requestUrl));
}
public class LoggingCallback implements CachedOutputStreamCallback {
private final String requestUrl;
/**
*
* #param requestUrl requestUrl.
*/
public LoggingCallback(final String requestUrl) {
this.requestUrl = requestUrl;
}
/**
* #param cos CachedOutputStream.
*/
public void onFlush(final CachedOutputStream cos) { //NOPMD
}
/**
* #param cos CachedOutputStream.
*/
public void onClose(final CachedOutputStream cos) {
try {
StringBuilder builder = new StringBuilder();
cos.writeCacheTo(builder, limit);
LOG.info("Request object for " + requestUrl + " :" + builder.toString());
} catch (Exception e) {
LOG.info("Error occured writing the response object for " + requestUrl);
}
}
}
Update:Since you are in Out chain you may need to get the In message from where you can get the request URI since the Request URI may null for out going response message.
You may try like this to get the Incoming message:
Message incoming = message.getExchange().getInMessage();
Then I think you should be able to get the Request URI using:
String requestURI = (String) incoming.get(Message.REQUEST_URI);
or
String endpointURI = (String) incoming.get(Message.ENDPOINT_ADDRESS);
If this is still not working, try to run the interceptor in PRE_STREAM phase like Phase.PRE_STREAM in your constructor.
You can also try to get the message from Interceptor Chain like this:
PhaseInterceptorChain chain = message.getInterceptorChain();
Message currentMessage = chain.getCurrentMessage();
HttpServletRequest req = (HttpServletRequest) currentMessage.get("HTTP.REQUEST");
I have a web reference created from the WSDL, but I'm not allowed to call the function unless I pass in the username / password; the original code for the XML toolkit was:
Set client = CreateObject("MSSOAP.SOAPClient30")
URL = "http://" & host & "/_common/webservices/Trend?wsdl"
client.mssoapinit (URL)
client.ConnectorProperty("WinHTTPAuthScheme") = 1
client.ConnectorProperty("AuthUser") = user
client.ConnectorProperty("AuthPassword") = passwd
On Error GoTo err
Dim result1() As String
result1 = client.getTrendData(expression, startDate, endDate,
limitFromStart, maxRecords
How do I add the AuthUser/AuthPassword to my new code?
New code:
ALCServer.TrendClient tc = new WindowsFormsApplication1.ALCServer.TrendClient();
foreach(string s in tc.getTrendData(textBox2.Text, "5/25/2009", "5/28/2009", false, 500))
textBox1.Text+= s;
Found it: Even if Preauthenticate==True, it doesn't do it. You have to overried the WebRequest:
protected override System.Net.WebRequest GetWebRequest(Uri uri)
{
HttpWebRequest request;
request = (HttpWebRequest)base.GetWebRequest(uri);
if (PreAuthenticate)
{
NetworkCredential networkCredentials =
Credentials.GetCredential(uri, "Basic");
if (networkCredentials != null)
{
byte[] credentialBuffer = new UTF8Encoding().GetBytes(
networkCredentials.UserName + ":" +
networkCredentials.Password);
request.Headers["Authorization"] =
"Basic " + Convert.ToBase64String(credentialBuffer);
}
else
{
throw new ApplicationException("No network credentials");
}
}
return request;
}
Since it gets created as a partial class, you can keep the stub in a separate file and rebuilding the Reference.cs won't clobber you.