|
You're welcome!
"I have no idea what I did, but I'm taking full credit for it." - ThisOldTony
"Common sense is so rare these days, it should be classified as a super power" - Random T-shirt
AntiTwitter: @DalekDave is now a follower!
|
|
|
|
|
viming wrote: should be sent out after sockct.send
That is what I thought a long time ago.
But a 'socket' is just a implementation of the protocol 'TCP' (built on 'IP') and that is how it works. Actually a socket just connects to the OS driver that implements that.
I found that in practice it doesn't matter. It gets sent quickly enough.
Other thing you might keep in mind is that only writes, not reads, require that a socket is actually communicating. Thus if you unplug your computer from the network while a computer at the other end it waiting ('read') for you to send something it will stay that way forever (while application is running.)
There are several ways that can happen usually involving infrastructure failures. But just a simple as someone accidently unplugging a network cable (plugging the cable back in does not fix that.)
That is why reads must set a timeout. Every socket implementation I have used always sets that to infinite by default.
|
|
|
|
|
I have a problem with this code, because it gives me following error message
Object reference not set to an instance of an object when I use the line
values[countValues] = reader2.GetString("textinfo"); in the code below
Can someone help me?
<pre lang="C#">
public static string[] values;
int countValues = 0;
using (var connection = new MySqlConnection(connString))
{
connection.Open();
string query = "select * from showvalues where idvalue = '" + idStatus + "'";
using (var command2 = new MySqlCommand(query, connection))
{
using (var reader2 = command2.ExecuteReader())
{
while (reader2.Read())
{
listBoxMeasurement.Items.Add(reader2.GetString("textinfo"));
values[countValues] = reader2.GetString("textinfo");
countValues++;
}
countValues = 0;
connection.Close();
}
}
}
|
|
|
|
|
The values array doesn't exist. You defined it as something that CAN hold an array, but you never defined an array for it to hold.
An array can only exist when it is told how many elements it can hold:
public static string[] values;
values = new string[20];
|
|
|
|
|
A couple of things:
1) This is one of the most common problems we get asked, and it's also the one we are least equipped to answer, but you are most equipped to answer yourself.
Let me just explain what the error means: You have tried to use a variable, property, or a method return value but it contains null - which means that there is no instance of a class in the variable.
It's a bit like a pocket: you have a pocket in your shirt, which you use to hold a pen. If you reach into the pocket and find there isn't a pen there, you can't sign your name on a piece of paper - and you will get very funny looks if you try! The empty pocket is giving you a null value (no pen here!) so you can't do anything that you would normally do once you retrieved your pen. Why is it empty? That's the question - it may be that you forgot to pick up your pen when you left the house this morning, or possibly you left the pen in the pocket of yesterday's shirt when you took it off last night.
We can't tell, because we weren't there, and even more importantly, we can't even see your shirt, much less what is in the pocket!
Back to computers, and you have done the same thing, somehow - and we can't see your code, much less run it and find out what contains null when it shouldn't.
But you can - and Visual Studio will help you here. Run your program in the debugger and when it fails, it will show you the line it found the problem on. You can then start looking at the various parts of it to see what value is null and start looking back through your code to find out why. So put a breakpoint at the beginning of the method containing the error line, and run your program from the start again. This time, the debugger will stop before the error, and let you examine what is going on by stepping through the code looking at your values.
But we can't do that - we don't have your code, we don't know how to use it if we did have it, we don't have your data. So try it - and see how much information you can find out!
2) Never concatenate strings to build a SQL command. It leaves you wide open to accidental or deliberate SQL Injection attack which can destroy your entire database. Always use Parameterized queries instead.
When you concatenate strings, you cause problems because SQL receives commands like:
SELECT * FROM MyTable WHERE StreetAddress = 'Baker's Wood' The quote the user added terminates the string as far as SQL is concerned and you get problems. But it could be worse. If I come along and type this instead: "x';DROP TABLE MyTable;--" Then SQL receives a very different command:
SELECT * FROM MyTable WHERE StreetAddress = 'x';DROP TABLE MyTable; Which SQL sees as three separate commands:
SELECT * FROM MyTable WHERE StreetAddress = 'x'; A perfectly valid SELECT
DROP TABLE MyTable; A perfectly valid "delete the table" command
And everything else is a comment.
So it does: selects any matching rows, deletes the table from the DB, and ignores anything else.
So ALWAYS use parameterized queries! Or be prepared to restore your DB from backup frequently. You do take backups regularly, don't you?
"I have no idea what I did, but I'm taking full credit for it." - ThisOldTony
"Common sense is so rare these days, it should be classified as a super power" - Random T-shirt
AntiTwitter: @DalekDave is now a follower!
|
|
|
|
|
OriginalGriff wrote: It's a bit like a pocket:
Nice analogy.
|
|
|
|
|
I'm using the predicate builder like this:
foreach (var vendorAssignment in vendorAssignments)
{
var jobPredicate = PredicateBuilder.New<Job>();
jobPredicate = jobPredicate.And(x => x.AppCompanyId == 1);
jobPredicate = jobPredicate.And(x => !x.DeletedDT.HasValue);
jobPredicate = jobPredicate.And(x => x.Id == vendorAssignment.ParentId);
var job = (from j in dc.Jobs
select j).Where(jobPredicate).FirstOrDefault();
}
Do I need to redefine the PredicateBuilder for each loop iteration? Or is it possible to somehow do this?
var jobPredicate = PredicateBuilder.New<Job>();
jobPredicate = jobPredicate.And(x => x.AppCompanyId == 1);
jobPredicate = jobPredicate.And(x => !x.DeletedDT.HasValue);
foreach (var vendorAssignment in vendorAssignments)
{
jobPredicate = jobPredicate.And(x => x.Id == vendorAssignment.ParentId);
var job = (from j in dc.Jobs
select j).Where(jobPredicate).FirstOrDefault();
}
Is there some way to remove the job part somehow?
In theory, theory and practice are the same. But in practice, they never are.”
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
|
|
|
|
|
There is no way to remove part of the predicate. Once it's built, it stays that way.
In your example, since you're adding more and more And clauses in a loop and executing the query in each iteration of the loop, only the first query is going to match anything. All subsequent queries will try to match a single ID value against multiple values at the same time and fail. An ID cannot be both, for example, 2 and 3 at the same time.
You have two choices. If you have a small number of vendor assignments, you can change the And to an Or and execute the query once. I don't know if this is going to work for you as I don't know exactly what you're doing:
foreach (var vendorAssignment in vendorAssignments)
{
jobPredicate = jobPredicate.Or(x => x.Id == vendorAssignment.ParentId);
}
var job = (from j in dc.Jobs
select j).Where(jobPredicate).FirstOrDefault();
OR, and this will probably work better for you, you can build a base predicate and just use that as a template to append an And clause to it:
var basePredicate = PredicateBuilder.New<Job>();
basePredicate = basePredicate.And(x => x.AppCompanyId == 1);
basePredicate = basePredicate.And(x => !x.DeletedDT.HasValue);
foreach (var vendorAssignment in vendorAssignments)
{
var jobPredicate = basePredicate.And(x => x.Id == vendorAssignment.ParentId);
var job = (from j in dc.Jobs
select j).Where(jobPredicate).FirstOrDefault();
}
|
|
|
|
|
Thanks Dave. I actually have 3 different queries that use AppCompanyId and DeletedDT, so I think the base query is what I want.
In theory, theory and practice are the same. But in practice, they never are.”
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
|
|
|
|
|
if your intent is to chain Predicates: maybe a wild idea, but take a look at Array.TrueForAll [^].
«The mind is not a vessel to be filled but a fire to be kindled» Plutarch
|
|
|
|
|
There are a couple things to be done here:
(from j in dc.Jobs
select j)
That, by itself, isn't doing much, except adding a pointless loop. "dc.Jobs " by itself, will do the same thing.
var jobPredicate = PredicateBuilder.New<Job>();
jobPredicate = jobPredicate.And(x => x.AppCompanyId == 1);
jobPredicate = jobPredicate.And(x => !x.DeletedDT.HasValue);
Unless there are some logic you've left out, which makes this optional, building the predicate this way is unnecessary. So, unless you have something like:
var jobPredicate = PredicateBuilder.New<Job>();
if (forApp1only)
jobPredicate = jobPredicate.And(x => x.AppCompanyId == 1);
if (!includeDeleted)
jobPredicate = jobPredicate.And(x => !x.DeletedDT.HasValue);
you could instead use just:
dc.Jobs.Where(job=> job.AppCompanyId == 1 && !job.DeletedDT.HasValue)
Which would mean your solution is just:
var job = dc.Jobs
.Where(job=> job.AppCompanyId == 1 && !job.DeletedDT.HasValue && job.Id == vendorAssignment.ParentId)
.FirstOrDefault();
But, let's say you really do need to use PredicateBuilder, still no problem, as you can repeat Where clauses:
var job = dc.Jobs
.Where(jobPredicate)
.Where(job=> job.Id == vendorAssignment.ParentId)
.FirstOrDefault();
Which we can shorten to:
var job = dc.Jobs
.Where(jobPredicate)
.FirstOrDefault(job=> job.Id == vendorAssignment.ParentId)
Truth,
James
|
|
|
|
|
Hi, I am new to this platform also new to C# code. I want to communicate with my Cobas e411 machine and receive data in text box but no data being received.
here is my code what i used. Kindly help
Kindly share the code for receiving the data from machine. I tried but its not working. No Data being received. My code is below.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO.Ports;
namespace New_Interfacing
{
public partial class Form1 : Form
{
private SerialPort _serialPort;
private const int BaudRate = 9600;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
string[] portNames = SerialPort.GetPortNames();
foreach (var portName in portNames)
{
comboBox1.Items.Add(portName);
}
comboBox1.SelectedIndex = 0;
}
private void button1_Click(object sender, EventArgs e)
{
_serialPort = new SerialPort(comboBox1.Text, BaudRate, Parity.None, 8, StopBits.One);
_serialPort.DataReceived += SerialPortOnDataReceived;
_serialPort.Open();
textBox1.Text = "Listening on " + comboBox1.Text + "...";
}
private delegate void Closure();
private void SerialPortOnDataReceived(object sender, SerialDataReceivedEventArgs serialDataReceivedEventArgs)
{
if (InvokeRequired)
BeginInvoke(new Closure(() => { SerialPortOnDataReceived(sender, serialDataReceivedEventArgs); }));
else
{
while (_serialPort.BytesToRead > 0)
{
textBox1.Text += string.Format("{0:X2} ", _serialPort.ReadByte());
}
}
}
}
}
modified 28-Jun-23 5:33am.
|
|
|
|
|
Use the debugger to see when the SerialPortOnDataReceived event gets called, and what data gets captured. Also you need to ensure that the client device is actually sending to the correct port.
|
|
|
|
|
Start at the beginning: use HyperTerminal or similar to check that the PC can "see" the device, and that data is being received and is at least slightly comprehensible.
If it isn't, then you need to fix that first!
When it is, then move on to code - and use the debugger to find out if the events are firing correctly - I'd add an SerialPort.ErrorReceived Event (System.IO.Ports) | Microsoft Learn[^] handler as well, in case the data format isn't what you think it is.
"I have no idea what I did, but I'm taking full credit for it." - ThisOldTony
"Common sense is so rare these days, it should be classified as a super power" - Random T-shirt
AntiTwitter: @DalekDave is now a follower!
|
|
|
|
|
I don't know this Device ... but when we speak about serial communication we have normally a Handshake between the Application and the Device.
So I suggest that you carefully read the Documantation of this Devide and try to find out how to communicate with it. I don't believe that it is sending Bytes without an request to do it ...
|
|
|
|
|
In general that question is surprisingly popular on this site. Having been asked multiple times over the years. General answer to all of those is to find the specification for the device and then implement it.
Member 14930272 wrote: new to C# code. I want to communicate with my Cobas e411 machine
Presumably you are not new to programming and are at least mid-level programmer in some other programming language. So 3-5 years of professional experience. Otherwise this is going to be a very difficult task for you. It would be a non-trivial task for me and I have many years of experience and have interfaced with multiple devices including serial port devices in the past.
Steps
1. Learn about serial programming in general
2. Find the protocol/communication specification. You MUST have this. Be careful if googling since I came across at least one site that seemed sketchy. But since you presumably have the actual machine maybe you have a business account that will provide it.
3. Study the specification. Read it end to end. Don't skim.
4. Find some examples in C# for serial communication. NOT for this device. But rather just how to use serial ports. Maybe find several.
5. With all of the above you can probably start laying out a solution to your actual problem.
|
|
|
|
|
Thank you brother. I ll try and then will revert.
|
|
|
|
|
I'd attempt explicit reads and track "bytes read" before depending on the (flaky, IMO) received event.
"Before entering on an understanding, I have meditated for a long time, and have foreseen what might happen. It is not genius which reveals to me suddenly, secretly, what I have to say or to do in a circumstance unexpected by other people; it is reflection, it is meditation." - Napoleon I
|
|
|
|
|
We have an an app that allows the user to import their Google contacts. We're modifying it because Google changed their auth process.
The idea is to call the Google Auth page and use an HTTPListener to listen on a port for the redirect URI. I went to the Google API Console [^]and set the Redirect URI to "https://127.0.0.1". We can't hardcode a port here.
There's a WPF sample from Google[^] here. Copy to a WPF window to see how it works.
So I set up the HTTPListener to handle the callback. The problem is that by using a random port number, how can you specify a callback URI in the control panel? Here's my code:
public async Task TryAuthorizeAsync()
{
string state = RandomDataBase64url(32);
string codeVerifier = RandomDataBase64url(32);
string codeChallenge = Base64urlencodeNoPadding(SHA256(codeVerifier));
string localHost = $"https://{IPAddress.Loopback}";
string listenerURI = $"{localHost}:{GetRandomUnusedPort()}/";
var listener = new HttpListener();
RaiseStatusChanged($"listening on {listenerURI}");
listener.Prefixes.Add(listenerURI);
listener.Start();
var authorizationRequest = $"{AuthorizationEndpoint}?response_type=code&" +
$"scope=openid%20profile&" +
$"redirect_uri={Uri.EscapeDataString(localHost)}&" +
$"client_id={ClientID}&" +
$"state={state}&" +
$"code_challenge={codeChallenge}&" +
$"code_challenge_method={CODE_CHALLENEGE_METHOD}";
Process.Start(authorizationRequest);
bool success = false;
await Task.Run(() =>
{
IAsyncResult context2 = listener.BeginGetContext(new AsyncCallback(result => ListenerCallback(result, state, codeVerifier, listenerURI)), listener);
if (HANDLE_TIMEOUT)
{
success = context2.AsyncWaitHandle.WaitOne(RESPONSE_TIMEOUT, true);
}
});
if (HANDLE_TIMEOUT && !success)
{
RaiseAuthorizationTimedOut();
}
}
When I run this, the user's Google auth page opens in the browser and when the user selects their account and authorizes, but the ListenerCallback never fires.
What I do see is the page directs to
This site can't be reached
127.0.0.1 refused to connect
The problem seems to be is that the auth needs the redirect port number. But we can't use a dedicated port number in the Google API Console, so how then can I redirect to the listener method?
In theory, theory and practice are the same. But in practice, they never are.”
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
modified 23-Jun-23 12:30pm.
|
|
|
|
|
The listener listens on a single port.
The URL MUST specify the port. There is no other option.
That is fundamental to how HTTP and the underlying TCP/IP works.
After that I am not sure where your confusion lies.
You do realize that you can and should use a static port right? Same port for all customers/clients? The additional information in the URL differentiates each of them.
Also presumably the code above is just test code, because you would need a fixed service listener that responds to those requests. Can't create the listener in the same code that initiates the request.
|
|
|
|
|
jschell wrote: You do realize that you can and should use a static port right?
That's the problem. We can't specify a port in the Google Console. The port needs to be random at runtime
In theory, theory and practice are the same. But in practice, they never are.”
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
|
|
|
|
|
Kevin Marois wrote: We can't specify a port in the Google Console. Is the problem that there is no separate input field for the port number? In that case, have you tried putting the port number into the URL?
http://127.0.01:5687
5687 is the port number.
The difficult we do right away...
...the impossible takes slightly longer.
|
|
|
|
|
No, we are not allowed to use a static port
In theory, theory and practice are the same. But in practice, they never are.”
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
|
|
|
|
|
Kevin Marois wrote: The port needs to be random at runtime
Then you will need to put in in the URL.
As I noted the URL allows for a port in it. So you can indeed put it in there.
But that means you will need to fly the server every time. No idea what that will do to your security model. Certainly won't work without a range since some ports are required and some are considered high security risks (even when something else it attached.)
And for some reason that it will not accept a perfectly valid URL with a port then you are done. Your solution will not work.
Summarizing above.
1. You say the server port must be random.
2. You must include the port in the URL
3. Either 1 is false, or 2 must be true or your solution will not work
|
|
|
|
|
I agree, and I'm not sure how else I would do this.
What it comes down to is waiting for the OAuth to complete and getting the reponse url. Do you know of any other way of doing this other than using an HTTPListener?
In theory, theory and practice are the same. But in practice, they never are.”
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
|
|
|
|
|