C# RichTextBox Displaying Random Format - serial-port

I have an RS232 communication app with 2 RichTextBox forms. One form is for logging "Outgoing" messages and the other form is for recieving "Incoming" messages from the port. I've used the same syntax for logging messages but for some reason I get random formats in my "Incoming" window (reading from the port).
Is there a way to get the "Incoming" box to display each incoming response byte[] on a new line? I am using a hyper-terminal so anything I send out should come back immediately through the same port.
Both RTB windows use the following log method
private void Log(LogMsgType msgtype, string msgOut)
{
rtbOutgoing.Invoke(new EventHandler(delegate
{
rtbOutgoing.SelectedText = string.Empty;
rtbOutgoing.SelectionFont = new Font(rtbOutgoing.SelectionFont, FontStyle.Bold);
rtbOutgoing.SelectionColor = LogMsgTypeColor[(int)msgtype];
rtbOutgoing.AppendText(msgOut);
rtbOutgoing.ScrollToCaret();
}));
}

Based on your comment, you should be able to try something like this. We're going to change what i.ToString() is outputting so that it's converted to newline delimited data instead of space-delimited:
Try this:
LogOutgoing(LogMsgType.Outgoing, "Short Address" + i.ToString().Replace(" ", "\n") + "\n");
That'll change all spaces into "\n" before the string is sent to the log() function.

Related

How do I parse specific data from a website within Codename One?

I have run into a road block developing my Codename One app. One of my classes in my project parses 3 specific html "td" elements from a website and saves the text to a string where I then input that text data into a Codename One multibutton. I originally used jSoup for this operation but soon realized that Codename One doesn't support 3rd party jar files so I used this method as shown below.
public void showOilPrice() {
if (current != null) {
current.show();
return;
}
WebBrowser b = new WebBrowser() {
#Override
public void onLoad(String url) {
BrowserComponent c = (BrowserComponent) this.getInternal();
JavascriptContext ctx = new JavascriptContext(c);
String wtiLast = (String) ctx.get("document.getElementById('pair_8849').childNodes[4].innerText");
String wtiPrev = (String) ctx.get("document.getElementById('pair_8849').childNodes[5].innerText");
String wtiChange = (String) ctx.get("document.getElementById('pair_8849').childNodes[8].innerText");
Form op = new Form("Oil Prices", new BoxLayout(BoxLayout.Y_AXIS));
MultiButton wti = new MultiButton("West Texas Intermediate");
Image icon = null;
Image emblem = null;
wti.setEmblem(emblem);
wti.setTextLine2("Current Price: " + wtiLast);
wti.setTextLine3("Previous: " + wtiPrev);
wti.setTextLine4("Change: " + wtiChange);
op.add(wti);
op.show();
}
};
b.setURL("https://sslcomrates.forexprostools.com/index.php?force_lang=1&pairs_ids=8833;8849;954867;8988;8861;8862;&header-text-color=%23FFFFFF&curr-name-color=%230059b0&inner-text-color=%23000000&green-text-color=%232A8215&green-background=%23B7F4C2&red-text-color=%23DC0001&red-background=%23FFE2E2&inner-border-color=%23CBCBCB&border-color=%23cbcbcb&bg1=%23F6F6F6&bg2=%23ffffff&open=show&last_update=show");
}
This method works in the simulator (and gives a "depreciated API" warning), but does not run when I submit my build online after signing. I have imported the parse4cn1 and cn1JSON libraries and have gone through a series of obstacles but I still receive a build error when I submit. I want to start fresh and use an alternative method if one exists. Is there a way that I can rewrite this segment of code without having to use these libraries? Maybe by using the XMLParser class?
The deprecation is for the WebBrowser class. You can use BrowserComponent directly so WebBrowser is redundant in this case.
I used XMLParser for this use case in the past. It should work with HTML as it was originally designed to show HTML.
It might also be possible to port JSoup to Codename One although I'm not sure about the scope of effort involved.
It's very possible that onLoad isn't invoked for a site you don't actually see rendered so the question is what specifically failed on the device?

Using SFTP File Name in Logic Apps

I have a simple Logic App that uses a SFTP connector, followed by a condition with an expression that states:
Object Name: File Name
Relationship: starts with
Value: '943'
The expression ends up being:
"#startsWith(triggerOutputs()['headers']['x-ms-file-name'], '''943''')"
But the condition always fails even when the file starts with 943.
When trying to debug this I decided to write the "file name" property to the body of a Service Bus Queue and then read it from a simple Windows app. When getting the body as a string, it always threw an exception. I had to rewrite it to use a stream to read it.
Failed Code:
Dim s as String = message.GetBody(of String)()
Working Code:
Dim stream As Stream = message.GetBody(Of Stream)()
Dim reader As StreamReader = New StreamReader(stream)
Dim s As String = reader.ReadToEnd
Does this mean "file name" is not a string but something else like a byte array? How do I get my condition in my Logic App to work properly?
Try update
"#startsWith(triggerOutputs()['headers']['x-ms-file-name'], '''943''')"
to
"#startsWith(triggerOutputs()['headers']['x-ms-file-name'], '943')"
Looks like basic mode will treat 123 as int, but adding additional quotes when entered '123', so you will need to make the change by switching to advanced mode.

are these cxf/ws-security properties set correctly? (getting TPE1122 error, "WS Security Header invalid")

We're trying to send a signed, partially encrypted SOAP message to the IRS using CXF. We think we're following all their instructions but there are ambiguities. Some of the Signature and Encryption properties could be set in several ways, but none of the permutations I've tried get us past the dreaded "TPE1122" error (WS Security Header invalid). If anyone has done this successfully, is there some property we're failing to set? I'm especially unsure about the encryption algorithm setting and whether the whole element should be encrypted or just the 3 header elements within it. Thanks.
BulkRequestTransmitterService ss = new BulkRequestTransmitterService(wsdlURL, SERVICE_NAME);
BulkRequestTransmitterPortType port = ss.getBulkRequestTransmitterPort();
org.apache.cxf.endpoint.Client client = ClientProxy.getClient(port);
// set up MTOM
Binding binding = ((BindingProvider)port).getBinding();
((SOAPBinding)binding).setMTOMEnabled(true);
// set output properties
Map<String, Object> outProps = new HashMap<String, Object>();
outProps.put("action", "Timestamp Signature Encrypt");
outProps.put("passwordType", "PasswordDigest");
outProps.put("signatureUser", "[REDACTED]";
outProps.put(WSHandlerConstants.SIG_KEY_ID, "X509KeyIdentifier");
outProps.put("passwordCallbackClass", "UTPasswordCallback");
outProps.put("encryptionUser", "irs");
outProps.put("encryptionPropFile", "encryption.properties");
outProps.put("encryptionKeyIdentifier", "DirectReference");
outProps.put("encryptionKeyTransportAlgorithm", "http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p");
// ENC_SYM_ALGO: what is the default? what should correct value be? and are these two lines equivalent?
outProps.put(WSHandlerConstants.ENC_SYM_ALGO, WSConstants.TRIPLE_DES);
outProps.put("encryptionSymAlgorithm", "http://www.w3.org/2001/04/xmlenc#tripledes-cbc");
// do we encrypt each of the three signed headers, or entire Signature element? have tried it both ways
outProps.put("encryptionParts",
//"{Element}{" + WSU_NS + "}Timestamp;"
//+"{Element}{urn:us:gov:treasury:irs:ext:aca:air:7.0}ACATransmitterManifestReqDtl;"
//+"{Element}{urn:us:gov:treasury:irs:ext:aca:air:7.0}ACABusinessHeader;");
"{Element}{http://www.w3.org/2000/09/xmldsig#}Signature;");
outProps.put("signaturePropFile", "signature.properties");
outProps.put("signatureAlgorithm", "http://www.w3.org/2000/09/xmldsig#rsa-sha1");
outProps.put("signatureParts",
"{Element}{" + WSU_NS + "}Timestamp;"
+ "{Element}{urn:us:gov:treasury:irs:ext:aca:air:7.0}ACATransmitterManifestReqDtl;"
+ "{Element}{urn:us:gov:treasury:irs:ext:aca:air:7.0}ACABusinessHeader;");
outProps.put(WSHandlerConstants.SIG_C14N_ALGO, "http://www.w3.org/2001/10/xml-exc-c14n#WithComments");
// is "Direct Reference" preferable? have tried it both ways
outProps.put(WSHandlerConstants.ENC_KEY_ID, "X509KeyIdentifier");
outProps.put("timeToLive", "600"); // = 10 min
outProps.put(WSHandlerConstants.MUST_UNDERSTAND, "false");
WSS4JOutInterceptor wssOut = new WSS4JOutInterceptor(outProps);
client.getOutInterceptors().add(wssOut);
// add gzip interceptor
GZIPOutInterceptor gz = new GZIPOutInterceptor();
gz.setForce(true);
client.getOutInterceptors().add(gz);
[ create & populate Manifest Detail here]
Header detailHeader = new Header(new QName("urn:us:gov:treasury:irs:ext:aca:air:7.0", "ACATransmitterManifestReqDtl"), aCATrnsmtManifestReqDtlType,
new JAXBDataBinding(ACATrnsmtManifestReqDtlType.class));
headers.add(detailHeader);
Header businessHeader = new Header(new QName("urn:us:gov:treasury:irs:ext:aca:air:7.0", "ACABusinessHeader"), aCABulkBusinessHeaderRequestType,
new JAXBDataBinding(ACABulkBusinessHeaderRequestType.class));
headers.add(businessHeader);
// add headers to Request
client.getRequestContext().put(Header.HEADER_LIST, headers);
// add namespaces:
Map<String, String> nsMap = new HashMap<>();
nsMap.put("soapenv", "http://schemas.xmlsoap.org/soap/envelope/");
nsMap.put("urn", "urn:us:gov:treasury:irs:ext:aca:air:7.0");
nsMap.put("urn1", "urn:us:gov:treasury:irs:common");
nsMap.put("urn2", "urn:us:gov:treasury:irs:msg:acabusinessheader");
nsMap.put("urn3", "urn:us:gov:treasury:irs:msg:irsacabulkrequesttransmitter");
nsMap.put("urn4", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");
client.getRequestContext().put("soap.env.ns.map", nsMap);
// then transmit, get TPE1122 error in Response
Bulit in CXF security will not work in IRS submission. You need to code your interceptors for matching IRS requirements.
I have a sample project ready, which can do submission and status requests. This is by no means a production code, but can be a starting point
https://github.com/sangramjadhav/irsclient
Please see application.yml file. You need to provide keystore and other configuration for submission to IRS
Thanks to both responders for your feedback. We have it working now and the main problem was that we were not supposed to use encryption. Everything in the sample I posted worked (including using CXF to sign certain parts of the header), but the encryption had to be removed.
It is indeed quite difficult to get everything right when transmitting to the IRS AIR system. The next hurdle was solved by changing a namespace in one of the wsdl-generated files, and then it went through, but their Linux system's value for the file size was 2 chars smaller than our Windows system's value - the culprit was the trailing CRLF.
I would be happy to answer specific questions if anyone is trying to do this as we did, using Java, Apache-CXF, and Windows.

Inline image rendered twice by OSX mail app

My .NET 4.5 web application uses class SmtpClient to create and send e-mail messages to various recipients.
Each e-mail message consists of:
an HTML message body
an embedded inline image (JPeg or PNG or GIF)
an attachment (PDF)
Sample code is below. It works fine, but there is one gripe from OSX users. Apple's standard mail app renders the image twice; once inlined in the message body, and again following the message body, next to the preview of the PDF attachment.
I tinkered with the following properties; none of which would help.
SmtpClient's DeliveryFormat
MailMessage's IsBodyHtml and BodyTransferEncoding
Attachment's MimeType, Inline, DispositionType, ContentId, FileName, Size, CreationDate, ModificationDate
If I compose a similar e-mail message in MS Outlook and send it off to the Apple user, the image is rendered once, inlined in the message body; exactly as I would like it to be. So apparently it is possible.
After reading this, I inspected the raw MIME data, and noticed Outlook uses multipart/related to group together the message body and the images.
My question:
How do I mimic Outlook's behavior with the classes found in System.Net.Mail?
Things I would rather not do:
Employ external images instead of embedded ones (many e-mail clients initially block these to protect recipient's privacy).
Use third party libraries (to avoid legal hassle). The SmtpDirect class I found here seems to solve the problem (though I got a server exception in return), but it is hard for me to accept a complete rewrite of MS's SmtpClient implementation is necessary for such a subtle change.
Send the e-mail message to a pickup folder, manipulate the resulting .eml file, push the file to our Exchange server.
Minimal code to reproduce the problem:
using System.IO;
using System.Net.Mail;
using System.Net.Mime;
namespace SendMail
{
class Program
{
const string body = "Body text <img src=\"cid:ampersand.gif\" /> image.";
static Attachment CreateGif()
{
var att = new Attachment(new MemoryStream(Resource1.ampersand), "ampersand.gif")
{
ContentId = "ampersand.gif",
ContentType = new ContentType(MediaTypeNames.Image.Gif)
};
att.ContentDisposition.Inline = true;
return att;
}
static Attachment CreatePdf()
{
var att = new Attachment(new MemoryStream(Resource1.Hello), "Hello.pdf")
{
ContentId = "Hello.pdf",
ContentType = new ContentType(MediaTypeNames.Application.Pdf)
};
att.ContentDisposition.Inline = false;
return att;
}
static MailMessage CreateMessage()
{
var msg = new MailMessage(Resource1.from, Resource1.to, "The subject", body)
{
IsBodyHtml = true
};
msg.Attachments.Add(CreateGif());
msg.Attachments.Add(CreatePdf());
return msg;
}
static void Main(string[] args)
{
new SmtpClient(Resource1.host).Send(CreateMessage());
}
}
}
To actually build and run it, you will need an additional resource file Resource1.resx with the two attachments (ampersand and Hello) and three strings host (the SMTP server), from and to (both of which are e-mail addresses).
(I found this solution myself before I got to posting the question, but decided to publish anyway; it may help out others. I am still open for alternative solutions!)
I managed to get the desired effect by using class AlternateView.
static MailMessage CreateMessage()
{
var client = new SmtpClient(Resource1.host);
var msg = new MailMessage(Resource1.from, Resource1.to, "The subject", "Alternative message body in plain text.");
var view = AlternateView.CreateAlternateViewFromString(body, System.Text.Encoding.UTF8, MediaTypeNames.Text.Html);
var res = new LinkedResource(new MemoryStream(Resource1.ampersand), new ContentType(MediaTypeNames.Image.Gif))
{
ContentId = "ampersand.gif"
};
view.LinkedResources.Add(res);
msg.AlternateViews.Add(view);
msg.Attachments.Add(CreatePdf());
return msg;
}
As a side effect, the message now also contains a plain text version of the body (for paranoid web clients that reject HTML). Though it is a bit of a burden ("Alternative message body in plain text" needs improvement), it does give you more control as to how the message is rendered under different security settings.

Attach An Email with an attachments to another email

So I know how to send emails with attachments... thats easy.
The problem now is I need to add an MailMessage, that has an attachment of its own, to a different MailMessage. This will allow the user to review things and take the email that is pre-made and send it if everything is ok.
I am not sure this will be the final work flow, but I would like to know if easy.
I see a bunch of software out there that is for money, the users getting these emails will be using an outlook client.
This would be deployed to a cheap shared hosting solutions, must be able to run in Meduim Trust!
I would prefer not to have to lic a 3rd party software, No $ :(
Any ideas would be awesome.
MailMessages cannot be attached to other MailMessages. What you will do is create an .msg file, which is basically a file that stores an e-mail and all of its attachments, and attach that to your actual MailMessage. MSG files are supported by Outlook.
For more information about the file extension, go here: http://www.fileformat.info/format/outlookmsg/
As Justin said, there is no facility to attach one MailMessage to another in the API. I worked around this using the SmtpClient to "deliver" my inner message to a directory, and then attached the resulting file to my outer message. This solution isn't terribly appealing, as it has to make use of the file system, but it does get the job done. It would be much cleaner if SmtpDeliveryMethod had a Stream option.
One thing to note, the SmtpClient adds X-Sender/X-Receiver headers for the SMTP envelope information when creating the message file. If this is an issue, you will have to strip them off the top of the message file before attaching it.
// message to be attached
MailMessage attachedMessage = new MailMessage("bob#example.com"
, "carol#example.com", "Attached Message Subject"
, "Attached Message Body");
// message to send
MailMessage sendingMessage = new MailMessage();
sendingMessage.From = new MailAddress("ted#example.com", "Ted");
sendingMessage.To.Add(new MailAddress("alice#example.com", "Alice"));
sendingMessage.Subject = "Attached Message: " + attachedMessage.Subject;
sendingMessage.Body = "This message has a message attached.";
// find a temporary directory path that doesn't exist
string tempDirPath = null;
do {
tempDirPath = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
} while(Directory.Exists(tempDirPath));
// create temp dir
DirectoryInfo tempDir = Directory.CreateDirectory(tempDirPath);
// use an SmptClient to deliver the message to the temp dir
using(SmtpClient attachmentClient = new SmtpClient("localhost")) {
attachmentClient.DeliveryMethod
= SmtpDeliveryMethod.SpecifiedPickupDirectory;
attachmentClient.PickupDirectoryLocation = tempDirPath;
attachmentClient.Send(attachedMessage);
}
tempDir.Refresh();
// load the created file into a stream
FileInfo mailFile = tempDir.GetFiles().Single();
using(FileStream mailStream = mailFile.OpenRead()) {
// create/add an attachment from the stream
sendingMessage.Attachments.Add(new Attachment(mailStream
, Regex.Replace(attachedMessage.Subject
, "[^a-zA-Z0-9 _.-]+", "") + ".eml"
, "message/rfc822"));
// send the message
using(SmtpClient smtp = new SmtpClient("smtp.example.com")) {
smtp.Send(sendingMessage);
}
mailStream.Close();
}
// clean up temp
mailFile.Delete();
tempDir.Delete();

Resources