|
Rather than building the request body by hand, you should use a JSON serializer to create it.
Add a NuGet package reference to JSON.NET[^], add a using directive for the Newtonsoft.Json namespace, and change your code to:
var body = new
{
No = tbNo.Text,
First_name = tbFirstName.Text,
Last_Name = tbLastName.Text,
FunctionName = tbFunctionName.Text,
};
string json = JsonConvert.SerializeObject(body);
byte[] data = Encoding.UTF8.GetBytes(json); NB: You'll want to use the UTF8 encoding rather than ASCII, since that's what you've declared in your content-type header.
I'd also be inclined to use the HttpClient class[^] rather than the low-level HttpWebRequest class:
Call a Web API From a .NET Client (C#) - ASP.NET 4.x | Microsoft Docs[^]
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
Hi Richard,
Thanks for your reply.
If I used the code you profided me but I cannot pass 'data' to _client as it expects a class and not Json data.
If I create a class and fill it, like in the MS Docs page you provided, than I get error 401 not authorized.
WorkersClass _data = new WorkersClass();
_data.E_Tag = string.Empty;
_data.No = tbNo.Text;
_data.First_name = tbFirstName.Text;
_data.Last_Name = tbLastName.Text;
_data.FunctionName = tbFunctionName.Text;
var url = await CreateWorkerAsync(_data);
static async Task<Uri> CreateWorkerAsync(WorkersClass _worker)
{
string _url = "https://api.businesscentral.dynamics.com/v2.0/SomeFunkyGuid/Sandbox/ODataV4/Company('CRONUS%20NL')/WorkersWebService";
string _userName = "UserName";
string _wsKey = "Password";
_client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(_userName, _wsKey);
HttpResponseMessage response = await _client.PostAsJsonAsync(_url, _worker);
response.EnsureSuccessStatusCode();
return response.Headers.Location;
}
I tried the following:
var body = new
{
E_Tag = string.Empty,
No = tbNo.Text,
First_name = tbFirstName.Text,
Last_Name = tbLastName.Text,
FunctionName = tbFunctionName.Text,
};
string json = JsonConvert.SerializeObject(body);
byte[] data = Encoding.UTF8.GetBytes(json);
var url = await CreateWorkerAsync(data);
The error I get is: Argument 1: cannot convert from byte[] to WorkersClass.
If I look at _client.PostAsJsonAsync, than I don't see a other solution where it says I can pass Json data?
I feel that I am close, but I think I miss the final step.
Hope you can help me.
Kind regards,
Clemens Linders
|
|
|
|
|
I was referring to the code from your original post, where you're constructing a JSON string manually:
Quote:
string body = "{" + Environment.NewLine +
"\"No\":" + tbNo.Text + "," + Environment.NewLine +
"\"First_name\":\"" + tbFirstName.Text + "\"," + Environment.NewLine +
"\"Last_Name\":\"" + tbLastName.Text + "\"," + Environment.NewLine +
"\"FunctionName\":\"" + tbFunctionName.Text + "\"," + Environment.NewLine +
"}";
byte[] data = Encoding.ASCII.GetBytes(body);
try
{
_request.ContentLength = data.Length;
Stream requestStream = _request.GetRequestStream();
requestStream.Write(data, 0, data.Length);
requestStream.Close();
HttpWebResponse _response = _request.GetResponse() as HttpWebResponse;
Console.WriteLine(_response.StatusCode);
}
catch (Exception ex)
{
} You don't need to worry about the JSON serialization with the HttpClient and the PostAsJsonAsync method - it handles the serialization for you.
You're getting a 401 error with your new code because you're passing the wrong values to the AuthenticationHeaderValue . The first parameter is the scheme, which should be "BASIC" , and the second is the parameter, which should be the combined username and password.
AuthenticationHeaderValue Constructor (System.Net.Http.Headers) | Microsoft Docs[^]
string _userName = "UserName";
string _wsKey = "Password";
byte[] authenticationParameter = Encoding.UTF8.GetBytes(_userName + ":" + _wsKey);
_client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(authenticationParameter));
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
Hi Richard,
I changed the CreateWorkersAsync:
static async Task<Uri> CreateWorkerAsync(WorkersClass _worker)
{
string _url = "https://api.businesscentral.dynamics.com/v2.0/SomeFunkyGuid/Sandbox/ODataV4/Company('CRONUS%20NL')/WorkersWebService";
string _userName = "UserName";
string _wsKey = "Password";
byte[] _authenticationParameter = Encoding.UTF8.GetBytes(_userName + ":" + _wsKey);
_client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(_authenticationParameter));
HttpResponseMessage response = await _client.PostAsJsonAsync(_url, _worker);
response.EnsureSuccessStatusCode();
return response.Headers.Location;
}
I didn't make any other changes.
I now no longer get the error 401 Not Authorized.
Now I get the error: 400 Bad request
We're one step closer.
Do you have any idea why I could get this Bad request??
Kind regards,
Clemens Linders
|
|
|
|
|
A 400 error would suggest that the server doesn't recognise the request format.
Are you certain they accept JSON requests? Your original post mentioned a SOAP request, which is a dialect of XML. If they only support SOAP requests, you won't be able to post JSON data to the service.
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
Hi Richard,
I am pretty sure that Json shouldn't be a problem, because when I read the data I use a Json deserializer.
There really are three different kind of web services:
- SOAP
- ODATA v3
- ODATA v4
This is the working code I use to read data using the ODATA V4 web service:
listBox1.Items.Clear();
WorkersReadFromAlWebService = new List<WorkerClass>();
string _url = "https://api.businesscentral.dynamics.com/v2.0/SomeFunkyGuid/Sandbox/ODataV4/Company('CRONUS%20NL')/WorkersWebService";
HttpWebRequest _request = (HttpWebRequest)WebRequest.Create(_url);
_request.ContentType = "application/json; charset=utf-8";
_request.Headers["Authorization"] = "Basic " + Convert.ToBase64String(Encoding.GetEncoding("ISO-8859-1").GetBytes("UserName:Password"));
_request.PreAuthenticate = true;
HttpWebResponse _response = _request.GetResponse() as HttpWebResponse;
using (Stream _responseStream = _response.GetResponseStream())
{
StreamReader _reader = new StreamReader(_responseStream, Encoding.UTF8);
string _content = _reader.ReadToEnd();
string _jasonPart = GetJsonPartMultiRecord(_content);
List<WorkerClass> _jWorkers = JsonConvert.DeserializeObject<List<WorkerClass>>(_jasonPart);
foreach (var _worker in _jWorkers)
{
WorkersReadFromAlWebService.Add(_worker);
listBox1.Items.Add(_worker.Last_Name + " / " + _worker.First_name + " (No: " + _worker.No + ")");
}
}
ClearWorker();
|
|
|
|
|
I have 2 pdf files pdf1 and pdf 2.I want to compare both pdf and should give result as 2 pdf outputs.
The 2 output pdf ,the changes should be highlighted in some color.say for output 1 -red color and output 2 pdf-green color for the change
Eg: input pdf 1 - text is :- I am anoop
input pdf 2 - text is :- I am aneesh
so the output should be as follows:
output pdf 3: I am anoop
output pdf 3: I am aneesh
means text anoop is changed to aneesh.So anoop in red color and aneesh in green color. Please provide the c# code for this.
|
|
|
|
|
No. This is not a code-to-order service.
We are more than willing to help those that are stuck: but that doesn't mean that we are here to do it all for you! We can't do all the work, you are either getting paid for this, or it's part of your grades and it wouldn't be at all fair for us to do it all for you.
So we need you to do the work, and we will help you when you get stuck. That doesn't mean we will give you a step by step solution you can hand in!
Start by explaining where you are at the moment, and what the next step in the process is. Then tell us what you have tried to get that next step working, and what happened when you did.
"I have no idea what I did, but I'm taking full credit for it." - ThisOldTony
AntiTwitter: @DalekDave is now a follower!
|
|
|
|
|
I'd suggest to read this: How to compare strings - C# Guide | Microsoft Docs and write a method which will beet your criteria for string comparison. At this moment you need to decide if below strings are equal or not:
I am anoop
I Am anOop
I aM Anoop
I am anoOP
i AM anoop
I Am ANoOP
i aM anOop
When you accomplish string comparison then you'll be ready to go further.
|
|
|
|
|
Looks like you've got a rival for this programming language[^] there.
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
|
Hi, I am having a hard time understanding some basic concepts in real time systems. I have tried reading up on it but when viewing a concrete system I can't really understand it.
The application prints the time, student name, student number and semester year as given in the setup in the program runs a certain amount of loops for all tasks.
Scheduler set up:
Name Delay
Thread#1 95ms
Thread#3 187ms
Thread#5 463ms
When code is executed it looks like this.
Print Out:
[T1]:11:30:45:808[T3]:11:30:45:825[T5]:11:30:45:825[T1]:Mark Johnson[T1]:152585[T3]:Mark Johnson[T1]:2020
[T5]:Mark Johnson[T1]:2020
[T5]:Mark Johnson[T1]:11:30:45:949[T3]:152585[T1]:Mark Johnson[T1]:2020
[T3]:2020[T5]:152585[T1]:2020[T3]:2020
What are the real time requirements of this application?
|
|
|
|
|
Windows is not and never has been a real time system: it's a multithreaded preemptive scheduling system, and that's different.
Thread delays aren't absolute values, they are minimum values: the thread will delay for at least Xms, and will be available to run from that point - but that doesn't mean it will run immediately, or even soon, depending on other threads in the system and the number of cores available to process them.
As the "Threads : Cores" ratio rises, more and more threads get delayed more and more.
You have no direct control at all over when a thread will run: all you can do is say "wait at least this long"; you can't even guarantee that a thread will complete an operation before a second thread gets in there - so when you are sharing a single resource (such as the console) between multiple threads, you can't even guarantee that each message you see will be complete, much less in an order you want!
"I have no idea what I did, but I'm taking full credit for it." - ThisOldTony
AntiTwitter: @DalekDave is now a follower!
|
|
|
|
|
Hi Original Griff, the question here is to analyze the system based on real-time requirements. The requirements will be any factor that may affect the running time of the tasks.The real-time involve tasks running in parallel, any common resources used by the system that will affect the timing and the time used by the application.
You are saying here that windows is not a real time system, but this is an app created to simulate a real time system that has some tasks running. That's a different thing inst it ?
If one disregards the CPU and computer memory which other resources are these tasks sharing when running?
|
|
|
|
|
What do you think?
It's your homework after all, not mine!
"I have no idea what I did, but I'm taking full credit for it." - ThisOldTony
AntiTwitter: @DalekDave is now a follower!
|
|
|
|
|
"Real-time" is like an ATM; you want your cash NOW.
Anything other than "real-time", means stuff might go into a "queue" for a while before it get processed, if there is "other" stuff that also needs doing.
As for "your" app, no one knows what it's doing so no one can tell you if it has a "real-time" requirement or not.
And simply printing the same static information over and over isn't anything; it's just nonsense.
It was only in wine that he laid down no limit for himself, but he did not allow himself to be confused by it.
― Confucian Analects: Rules of Confucius about his food
|
|
|
|
|
auting82 wrote: What are the real time requirements of this application? There are not any real time requirements, since all you are doing is printing some general information about people in your database.
|
|
|
|
|
Hi
this is shyam from hyderabad city
request to provide the c# code related to multiple csv file into datatable or database
of mssql database
thanks in advance
|
|
|
|
|
Sorry, these forums are not suited for code requests. There exist some sites where you can rent coders, but CP isn't one of them.
"Five fruits and vegetables a day? What a joke!
Personally, after the third watermelon, I'm full."
|
|
|
|
|
I have a Web API to send SMS to customers. Web API is up and running 24/7/365. Web API is running fine without any issues.
However, I am invoking the API everytime through PostMan tool. In order to avoid this manual intervention, I have written a console application, but that console application sometimes works, sometimes didn't. it stops abruptly without any reason, I tried to catch error, but no effect. The application has to run automatically with an interval of 5 minutes in day. Every 5 minute it has to run. If already previous task is running, then no need to start a new task. I have implemented this by using a ProcessMap table in Sql DB. So each time it starts, it checks if any sms task is running. if running,it will not start new, otherwise starts a new task.
My question is , is this the correct way to invoke the API automatically or is there any other better way to do this? Kindly hep.
|
|
|
|
|
Given your requirements, I'd be inclined to write a console application to call the API once and then exit. Then use the Windows Task Scheduler to schedule that application to run every five minutes.
By default, if the task is already running, Task Scheduler won't start it again, so you shouldn't need any SQL tables or additional checks.
As for fixing the crashes, you'll need to debug your application. If you want someone to help you fix the errors, we'll need to see the full error details, and the relevant parts of your code.
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
Thank you Richard. I think if you can clarify little bit on first portion of your reply, I will be able to fix my issue.
In my console application, I have invoked the API as below:
class Program
{
static void Main(string[] args)
{
RunAsync().GetAwaiter().GetResult();
Environment.Exit(0);
}
static async Task RunAsync()
{
string httpReasonStatus = string.Empty;
int reasoncode;
using (var client = new HttpClient())
{
string baseURL = ConfigurationManager.AppSettings["APIURL"].ToString().Trim();
client.BaseAddress = new Uri(baseURL);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
Console.WriteLine("Get");
HttpResponseMessage response = await client.GetAsync("/api/SendBulkSMS");
if (response.IsSuccessStatusCode)
{
reasoncode = (int)response.StatusCode;
httpReasonStatus = response.ReasonPhrase;
}
else
{
reasoncode = 0;
httpReasonStatus = "error";
}
}
}
}
How would you call the Console application once, and then use the Windows Scheduler to schedule the application without using Sql tables. I am also not in favour of using Sql tables, and looking for any other better ways. Can you please provide any guide on this? Thanks a lot for the support.
|
|
|
|
|
That code is already doing what I expected - it calls the API once and then exits. There's no code to check a SQL table to try to enforce a single instance.
The task scheduler hasn't changed very much since Vista. You just need to launch it and create a new task to run your console application:
How to Automatically Run Programs and Set Reminders With the Windows Task Scheduler[^]
NB: I'd be inclined to make a couple of changes to your code:
static class Program
{
static async Task<int> Main()
{
string baseURL = ConfigurationManager.AppSettings["APIURL"].Trim();
if (!Uri.TryCreate(baseURL, UriKind.Absolute, out var baseAddress))
{
Console.Error.WriteLine("Invalid API URL: '{0}'", baseURL);
return -1;
}
using (var client = new HttpClient())
{
client.BaseAddress = baseAddress;
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
Console.WriteLine("Get");
using (var response = await client.GetAsync("/api/SendBulkSMS"))
{
Console.WriteLine("{0}: {1}", response.StatusCode, response.ReasonPhrase);
if (response.IsSuccessStatusCode) return 0;
return (int)response.StatusCode;
}
}
}
} - Since C# 7.1, you can make the
Main method async . - You can return the exit code directly, rather than using
Environment.Exit . - You should avoid throwing an exception if the URL in the config file is invalid.
- You should wrap the
HttpResponseMessage in a using block. - There's no point in the
reasoncode and httpReasonStatus variables, since you never use them. - Console applications should generally return
0 if they succeed, and non-zero if they fail. The non-successful HTTP status code looks like a good candidate here.
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
<pre> Im creating a Xamarin.Android app and for database im using sqlite-net. I was trying to create a table with this structure
public class Templates
{
[PrimaryKey, AutoIncrement]
public int Id { get; set; }
public int Category { get; set; }
[TextBlob("imagesBlobbed")]
public List<int> Images { get; set; }
public string imagesBlobbed { get; set; }
}
but i want every time im adding a template to check if it already exist by checking the Images like this:
public static void AddTemplate(SQLiteConnection db, int category, List<int> images)
{
var alreadyExist = db.Table<templates>().Where(record => record.Images == images);
if (alreadyExist?.Count() == 0)
{
var template = new Templates()
{
Category = category,
Images = images,
};
db.InsertWithChildren(template, recursive: true);
}
}
but it's not working and i'm guessing it is not working because you cannot query with parameter "Images", in the database is stored as a blob. So im guessing i have to convert List to something else that is more easily supported in sqlite.
I'm thinking of using sqlite-net-extensions that support one to many relations and do something like this:
[Table("Templates")]
public class Template
{
[PrimaryKey, AutoIncrement]
public int Id { get; set; }
public int Category { get; set; }
[OneToMany]
public TemplateImage Images { get; set; } = new List<int>();
}
[Table("TemplateImages")]
public class TemplateImage
{
[PrimaryKey, AutoIncrement]
public int Id { get; set; }
public int Image1 { get; set; }
public int Image2 { get; set; }
public int Image3 { get; set; }
public int Image4 { get; set; }
public int Image5 { get; set; }
[ForeignKey(typeof(Template))]
public int TemplateId { get; set; }
}
In my application every template has 5 images, but this might change in the future. What is the correct approach according to DB design, to have a TemplateImage object with 5 images or to have only one image for every TemplateImage object like this:
[Table("Templates")]
public class Template
{
[PrimaryKey, AutoIncrement]
public int Id { get; set; }
public int Category { get; set; }
[OneToMany]
public List<templateimage> Images { get; set; } = new List<int>();
}
[Table("TemplateImages")]
public class TemplateImage
{
[PrimaryKey, AutoIncrement]
public int Id { get; set; }
public int Image { get; set; }
[ForeignKey(typeof(Template))]
public int TemplateId { get; set; }
}
Is the second approach slower? Is there any other better way for this?
|
|
|
|
|
Exoskeletor wrote: but it's not working and i'm guessing it is not working because you cannot query with parameter "Images", in the database is stored as a blob. So im guessing i have to convert List to something else that is more easily supported in sqlite. Comparing blobs isn't very efficient; make a hash-value of the blob (like md5), store that with the blob, and compare it using that. A hash-value would be like a fingerprint of your blob; it will change as soon as the image changes, but will result in the same values for the same images.
Exoskeletor wrote: In my application every template has 5 images, but this might change in the future. What is the correct approach according to DB design, to have a TemplateImage object with 5 images or to have only one image for every TemplateImage object like this: I'd have a table for the images; one field for the image, another field that holds the id of the template. That way you can have any number of images linked to the template.
Bastard Programmer from Hell
If you can't read my code, try converting it here[^]
"If you just follow the bacon Eddy, wherever it leads you, then you won't have to think about politics." -- Some Bell.
|
|
|
|
|