c# JSON Post Issue - c#

I can't work this one out. If I use NewtonSoft to serialize the object to JSON before a HTTP Post, I receive a 400 from the REST Service. If I just post the JSON as a string, in the below code as "jsonx" it works. However, if I compare the strings "json" and "jsonx" they're the same.
public async Task<String> TransferAsync(String fromAddress, Int64 amount, String toAddress, String assetId)
{
Models.CoinPrism.TransferRequest request = new CoinPrism.TransferRequest()
{
fees = 1000,
from = fromAddress,
};
request.to[0] = new CoinPrism.Transfer()
{
address = toAddress,
amount = amount,
asset_id = assetId
};
String json = Newtonsoft.Json.JsonConvert.SerializeObject(request);
String jsonX = "{ \"fees\": 1000, \"from\": \"1zLkEoZF7Zdoso57h9si5fKxrKopnGSDn\", \"to\": [ { \"address\": \"akSjSW57xhGp86K6JFXXroACfRCw7SPv637\", \"amount\": \"10\", \"asset_id\": \"AHthB6AQHaSS9VffkfMqTKTxVV43Dgst36\" } ]}";
Uri baseAddress = new Uri("https://api.coinprism.com/");
using (var httpClient = new HttpClient { BaseAddress = baseAddress })
{
using (var content = new StringContent(jsonX, System.Text.Encoding.Default, "application/json"))
{
using (var response = await httpClient.PostAsync("v1/sendasset?format=json", content))
{
string responseData = await response.Content.ReadAsStringAsync();
return responseData;
}
}
}
}
Models
public class TransferRequest
{
public Int64 fees { get; set; }
public String from { get; set; }
public Transfer[] to { get; set; }
public TransferRequest(Int32 n = 1)
{
this.to = new Transfer[n];
}
public TransferRequest(Transfer transfer)
{
this.to = new Transfer[1];
this.to[0] = transfer;
}
}
public class Transfer
{
public String address { get; set; }
public Int64 amount { get; set; }
public String asset_id { get; set; }
}

The reason of the error is that they are identical strings but with different encoding.
You are sending the wrong encoding for the string.
1- After serializing, convert the string to ANSI encoding (for example)
2- using (var content = new StringContent(jsonX, System.Text.Encoding.ANSI, "application/json)

Related

Updating Item in Sharepoint List with HttpClient through API fails with 403 FORBIDDEN (create and delete is working)

I try to do some CRUD operations on a sharepoint list, unfortunately I cannot update an item in the list. Since I can create and also delete items from the list, I think everything is fine with authentication and rights, but maybe I am not aware of some specific for the update process.
I have extracted the code from my libs to thrill it down to the most relevant lines, in an async method I first read the list and get the item to update
async Task Main()
{
var BaseUrl = "https://my_site/";
var credentials = new NetworkCredential("user", "pass", "domain");
string RequestDigest = null;
HttpClientHandler handler = new HttpClientHandler { Credentials = credentials };
var SpClient = new HttpClient(handler)
{
BaseAddress = new Uri(BaseUrl)
};
SpClient.DefaultRequestHeaders.Accept.Clear();
SpClient.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
var url = BaseUrl + $"_api/lists/getbytitle('Test')/items";
var response = await SpClient.GetAsync(url);
var data = await response.Content.ReadAsStringAsync();
if (response.StatusCode != HttpStatusCode.OK) throw new Exception(response.StatusCode.ToString() + " - " + response.RequestMessage.RequestUri);
SharepointListItems listEntries = JsonSerializer.Deserialize<SharepointListItems>(data);
var existing = listEntries.ListItems.FirstOrDefault(p => p.Title == "Eins");
This works fine, existing now contains the item from the list.
Now I tried to update this item:
// This will not work: StatusCode: 403, ReasonPhrase: 'FORBIDDEN', Version: 1.1, Content: System.Net.Http.HttpConnectionResponseContent, Headers:
existing.Title = "Changed";
string jsonString = JsonSerializer.Serialize<SharepointListItem>(existing);
So I tried to set up the sting for the item "by Hand" for testing purpose:
// This will also not work : StatusCode: 403, ReasonPhrase: 'FORBIDDEN', Version: 1.1, Content: System.Net.Http.HttpConnectionResponseContent, Headers:
// Prepare body string for testing
string jsonString = "{\"__metadata\": { \"type\": \"SP.Data.TestListItem\" }, \"Title\": \"Changed\"}";
Finally this is the code, that writes the item back to the list:
// write item back to list
if (RequestDigest == null || DateTime.Now > Convert.ToDateTime(RequestDigest.Split(',')[1]).AddSeconds(1800))
{
url = BaseUrl + "_api/contextinfo";
response = await SpClient.PostAsync(url, null);
data = response.Content.ReadAsStringAsync().Result;
var result = JsonSerializer.Deserialize<SharepointContext>(data);
RequestDigest = result.FormDigestValue;
SpClient.DefaultRequestHeaders.Remove("X-RequestDigest");
SpClient.DefaultRequestHeaders.Add("X-RequestDigest", RequestDigest);
SpClient.DefaultRequestHeaders.Add("X-HTTP-Method", "MERGE");
SpClient.DefaultRequestHeaders.Add("Accept", "application/json;odata=verbose");
}
if (existing.odataetag != null)
{
SpClient.DefaultRequestHeaders.Remove("If-Match");
SpClient.DefaultRequestHeaders.Add("If-Match", $"*");
}
var content = new StringContent(jsonString);
content.Headers.Clear();
content.Headers.Add("Content-Type", "application/json");
content.Headers.Add("X-RequestDigest", RequestDigest);
content.Headers.Add("X-HTTP-Method", "MERGE");
url = BaseUrl + $#"_api/lists/getbytitle('Test')/items({existing.Id})";
response = await SpClient.PostAsync(url, content);
Console.WriteLine(response.StatusCode);
response.Dump();
}
This sample I have extracted from my code and written in LinqPad. Here are the classes required for the full sample to run:
public class SharepointListItems
{
[JsonPropertyName("odata.metadata")]
public string odatametadata { get; set; }
[JsonPropertyName("value")]
public List<SharepointListItem> ListItems { get; set; }
}
public class SharepointListItem
{
public SharepointListItem() { }
[JsonPropertyName("odata.type")]
public string odatatype { get; set; }
[JsonPropertyName("odata.id")]
public string odataid { get; set; }
[JsonPropertyName("odata.etag")]
public string odataetag { get; set; }
[JsonPropertyName("odata.editLink")]
public string odataeditLink { get; set; }
public string Title { get; set; }
public int Id { get; set; }
}
public class SharepointContext
{
public string odatametadata { get; set; }
public int FormDigestTimeoutSeconds { get; set; }
public string FormDigestValue { get; set; }
public string LibraryVersion { get; set; }
public string SiteFullUrl { get; set; }
public string[] SupportedSchemaVersions { get; set; }
public string WebFullUrl { get; set; }
}
May anyone give any tips what I am doing wrong here?
As stated above the code runs fine on creating a new item. The only difference is that the body in this case only contains the item as Json without metadata and the etag header is not set.
Thank's for any hint.

RestSharp doesn't get data or content of response

I have a route in my web service that receives POST request with Json body and returns simple array in Json format. I'm using PostMan for testing route and it works perfectly. but when I'm using RestSharp it doesn't get any content (or data in deserialization case).
Here is my C# code :
public static async Task<string> UpdateProfile(Profile user, string serviceUrl)
{
string bodyraw = JsonConvert.SerializeObject(user)
var client = new RestClient(serviceUrl);
var request = new RestRequest();
request.Method = Method.POST;
request.Parameters.Clear();
request.AddParameter("application/json", bodyraw, ParameterType.RequestBody);
request.OnBeforeDeserialization = resp => { resp.ContentType = "application/json"; };
var response = await client.ExecuteTaskAsync<Profile>(request);
return response.Data.Address;
}
And here is the Profile Class:
public class Profile
{
public string Name { get; set; }
public string Family { get; set; }
public string Email { get; set; }
public string Mobile { get; set; }
public string Address { get; set; }
public string Postal_code { get; set; }
public string Education { get; set; }
public string Gender { get; set; }
public string Age { get; set; }
public string Default_contact { get; set; }
public override string ToString()
{
return string.Concat(Name," " ,Family, " ", Address);
}
}
And this is PostMan OutPut:
{
"Name": "Holma",
"Family": "Kool",
"Email": "dr#gmail.com",
"Mobile": "09063094744",
"Address": "some city- basic av. sq 60",
"Postal_code": "10246666",
"Education": "1",
"Gender": "male",
"Age": "35"
}
And the PHP code that I used is:
function silverum_update_user_profile($request ){
$parameters = $request->get_json_params();// this is a WordPress method and works just fine
$name=sanitize_text_field($parameters['name']);
$family=sanitize_text_field($parameters['family']);
$email=sanitize_text_field($parameters['email']);
$mobile=sanitize_text_field($parameters['mobile']);
$address=sanitize_text_field($parameters['address']);
$postal_code=sanitize_text_field($parameters['postal_code']);
$education=sanitize_text_field($parameters['education']);
$gender=sanitize_text_field($parameters['gender']);
$age=sanitize_text_field($parameters['age']);
$extdp = [
"Name"=>$name,
"Family"=>$family,
"Email"=>$email,
"Mobile"=>$mobile,
"Address"=>$address,
"Postal_code"=>$postal_code,
"Education"=>$education,
"Gender"=>$gender,
"Age"=>$age
];
return $extdp;
}
When PHP method returns "Parameter" its OK and both PostMan and RestSharp can see output content but when method Returns new Array only PostMan is able to recive returnd object. I spent a couple of hour on the issue but didn't get anywhere. help please.
Try using the AddJsonBody() method within the RestRequest object as opposed to adding the parameter manually.
public static async Task<string> UpdateProfile(Profile user, string serviceUrl)
{
var client = new RestClient(serviceUrl);
var request = new RestRequest();
request.Method = Method.POST;
request.AddJsonBody(user);
request.OnBeforeDeserialization = resp => { resp.ContentType = "application/json"; };
var response = await client.ExecuteAsync<Profile>(request);
return response.Data.Address;
}

Streaming Api consumption

I have an api http://oversea-download.hikvision.com/uploadfile/Leaflet/ISAPI/HIKVISION%20ISAPI_2.0-IPMD%20Service.pdf I want to receive which uses a HTTP get and wants connection keep-alive.
Once connected it sends XML responses which I want to deserialise. I've created a class to represent the data structure, but I'm not sure how to continually update a list or similar as and when the data is sent back, for example the response (from wireshark) looks like:
I'm not concerned with the parsing of data and updating the list, more how I can keep listening on a socket and see that its XML data and needs to be serialised.. without processing the stream into a buffer and looking for delimiters?
So far the code I had been unsuccessfully playing with looks like:
public static async Task NewTask()
{
var client = new RestClient("http://192.168.0.152:80/");
client.Authenticator = new HttpBasicAuthenticator("admin", "ThePassword");
client.Encoding = Encoding.UTF8;
var request = new RestRequest("ISAPI/Event/notification/alertStream", Method.GET);
request.AddHeader("Connection", "keep-alive");
request.AddHeader("Content-Type", "application/xml");
IRestResponse<EventNotificationAlert> response2 = client.Execute<EventNotificationAlert>(request);
var name = response2.Data.eventType;
Console.WriteLine(name);
//var asyncHandle = client.ExecuteAsync<EventNotificationAlert>(request, response => {
// Console.WriteLine(response.Data.eventDescription);
//});
}
and the class:
public class EventNotificationAlert
{
public string version { get; set; }
public string ipAddress { get; set; }
public string portNo { get; set; }
public string protocol { get; set; }
public string macAddress { get; set; }
public string channelID { get; set; }
public string dateTime { get; set; }
public string activePostCount { get; set; }
public string eventType { get; set; }
public string eventState { get; set; }
public string eventDescription { get; set; }
}
disregard my comment, can't format it.. this kind of works.. but given I get boundary and content-type text I've got crude processing in...
var messageBuffer = string.Empty;
var request = WebRequest.Create("http://192.168.0.152:80/ISAPI/Event/notification/alertStream");
request.Credentials = new NetworkCredential("admin", "ThePassword");
request.BeginGetResponse(ar =>
{
var req = (WebRequest)ar.AsyncState;
// TODO: Add exception handling: EndGetResponse could throw
using (var response = req.EndGetResponse(ar))
using (var reader = new StreamReader(response.GetResponseStream()))
{
// This loop goes as long as the api is streaming
while (!reader.EndOfStream)
{
var line = reader.ReadLine();
if (line == xmlEndStr)
{
messageBuffer += line;
GotMessage(messageBuffer);
messageBuffer = string.Empty;
}
else if (line.StartsWith("<"))
{
messageBuffer += line;
}
}
}
}, request);
static void GotMessage(string msg)
{
var mySerializer = new XmlSerializer(typeof(EventNotificationAlert));
var stringReader = new StringReader(msg);
var eventAlert = (EventNotificationAlert)mySerializer.Deserialize(stringReader);
Console.WriteLine($"DateTime: {eventAlert.dateTime} Channel: {eventAlert.channelID} Type: {eventAlert.eventType} Description: {eventAlert.eventDescription}");
}
Happy to hear of better ways (as you can tell I'm not great with c#!)

How to get UserContactLists from constant contact using c#

I am going to use Constant contact for email marketing. I am not getting how to get userContactList which are all there in my constant contact account.If anyone have any idea please help me.
Thanks in advance
Here is some code I wrote a while ago that returns the user list ID based on the name of an existing user list. its all C# and uses RESTSharp library which you can install inside your VS project using Nuget.
public static string GetContactListIDByListName(string listname)
{
feedData = string.Empty;
id = string.Empty;
name = string.Empty;
status = string.Empty;
modified_date = string.Empty;
created_date = string.Empty;
contact_count = 0;
Stream stream = null;
StreamReader streamReader = null;
var client = new RestClient(ccURL);
var request = new RestRequest("/v2/lists?modified_since=[DATE]&api_key=[API-KEY]", Method.GET);
request.AddHeader("Authorization", "Bearer [ACCESS-TOKEN]");
request.AddHeader("X-Originating-Ip", "[SERVER-IP]");
request.AddHeader("Accept", "application/json");
IRestResponse response = client.Execute(request);
feedData = response.Content;
// DESERIALIZE Mashery JSON Response
byte[] byteArray = Encoding.ASCII.GetBytes(feedData);
MemoryStream myStream = new MemoryStream(byteArray);
DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(Mashery.GetAllListsDef[]));
object result = serializer.ReadObject(myStream);
Mashery.GetAllListsDef[] jsonObj = result as Mashery.GetAllListsDef[];
foreach (Mashery.GetAllListsDef myResult in jsonObj)
{
if (myResult.name.ToUpper().Equals(listname.ToUpper()))
{
return myResult.id.ToString();
}
}
return "";
}
// JSON Definition For [GET All Lists] End Point Method
[Serializable, XmlRoot("GetAllListsDef"), DataContract(Name = "GetAllListsDef")]
public class GetAllListsDef
{
[XmlElement("id"), DataMember(Name = "id")]
public string id { get; set; }
[XmlElement("name"), DataMember(Name = "name")]
public string name { get; set; }
[XmlElement("status"), DataMember(Name = "status")]
public string status { get; set; }
[XmlElement("created_date"), DataMember(Name = "created_date")]
public string created_date { get; set; }
[XmlElement("modified_date"), DataMember(Name = "modified_date")]
public string modified_date { get; set; }
[XmlElement("contact_count"), DataMember(Name = "contact_count")]
public string contact_count { get; set; }
}

Unsupported Media Type error when posting to Web API

Making a windows phone application and although I may easily pull from my Web Api I am having trouble posting to it. Whenever posting to the api I get the "Unsupported Media Type" error message and I'm not sure as to why it is happening considering the class I using as the base for my JSON post is the same as the one used in the api.
PostQuote (Post Method)
private async void PostQuote(object sender, RoutedEventArgs e)
{
Quotes postquote = new Quotes(){
QuoteId = currentcount,
QuoteText = Quote_Text.Text,
QuoteAuthor = Quote_Author.Text,
TopicId = 1019
};
string json = JsonConvert.SerializeObject(postquote);
if (Quote_Text.Text != "" && Quote_Author.Text != ""){
using (HttpClient hc = new HttpClient())
{
hc.BaseAddress = new Uri("http://rippahquotes.azurewebsites.net/api/QuotesApi");
hc.DefaultRequestHeaders.Accept.Clear();
hc.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
HttpResponseMessage response = await hc.PostAsync(hc.BaseAddress, new StringContent(json));
if (response.IsSuccessStatusCode)
{
Frame.Navigate(typeof(MainPage));
}
else
{
Quote_Text.Text = response.StatusCode.ToString();
//Returning Unsupported Media Type//
}
}
}
}
Quotes and Topic (Model)
public class Quotes
{
public int QuoteId { get; set; }
public int TopicId { get; set; }
public string QuoteText { get; set; }
public string QuoteAuthor { get; set; }
public Topic Topic { get; set; }
public string QuoteEffect { get; set; }
}
//Topic Model//
public class Topic
{
public int TopicId { get; set; }
public string TopicName { get; set; }
public string TopicDescription { get; set; }
public int TopicAmount { get; set; }
}
You should set the media type when creating StringContent
new StringContent(json, Encoding.UTF32, "application/json");
I found this question while working on a quick and dirty reverse proxy. I needed form data and not JSON.
This did the trick for me.
string formData = "Data=SomeQueryString&Foo=Bar";
var result = webClient.PostAsync("http://XXX/api/XXX",
new StringContent(formData, Encoding.UTF8, "application/x-www-form-urlencoded")).Result;
To fix the unsupported media type I had to use HttpRequestMessage and add header to accept json with MediaTypeWithQualityHeaderValue like bellow.
var httpRequestMessage = new HttpRequestMessage
{
Content = new StringContent(json, Encoding.UTF8, "application/json")
};
httpRequestMessage.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var httpResponse = await _client.PostAsync("/contacts", httpRequestMessage.Content);

Categories

Resources