I'm currently working on a new "dashboard like" website where I need to show all message from an exchange 2016 mailbox (like gmail or any bootstrap email client template).
Currently, I'm able to retrieve the messages from the mailbox without problem by using the EWS API.
My problem is I really don't know which format (XML or JSON) is better to return the message content (ID,Body,subject and DateTimeReceived). I tried to store all messages in a multidimenssional array and a jagged array but when I tried to serialize them in a JSON string, I always get an "Unexpected token" error.
So my two questions are:
1) Is it better to use XML format than JSON considering the message's body can be a very long string?
2) Is there a better way to achieve what I what to do rather than an array converted by a JQuery script?
PS: I'm working on Visual Studio 2017 and the language used is C# with a bootstrap dashboard template. Also, I am totally new to web development(language, good coding habits and etc) but not to C# programming.
Here's my function to extract all messages from the mailbox and return a multidimensional array :
public string[,] getEmail() {
ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2010_SP1);
service.AutodiscoverUrl("testUser#myworkplace.com");
service.TraceEnabled = true;
service.TraceFlags = TraceFlags.All;
service.UseDefaultCredentials = true;
PropertySet itempropertyset = new PropertySet(BasePropertySet.FirstClassProperties);
itempropertyset.RequestedBodyType = BodyType.Text;
ItemView itemview = new ItemView(1000);
itemview.PropertySet = itempropertyset;
FindItemsResults < Item > findResults = service.FindItems(WellKnownFolderName.Inbox, itemview);
string[, ] emailArray = new string[findResults.TotalCount, 4];
int i = 0;
foreach(Item item in findResults.Items) {
message.Load(itempropertyset);
emailArray[i, 0] = message.Id.ToString();
emailArray[i, 1] = message.Subject;
emailArray[i, 2] = message.Body;
emailArray[i, 3] = message.DateTimeReceived.ToString();
i++;
}
return emailArray;
}
Any help would be appreciated.
If you're trying to get the data up to a web browser, you're most likely better off going with JSON. The browser has native code to parse JSON strings, and it's a very easy format both to create and parse.
That being said, you should still find a library to do the encoding for you. Pretty much all platforms will have some code to convert a set of nested Maps and Arrays to a JSON string, and that will help you avoid minor (but fatal) errors in actually formatting & parsing the document.
See also: JSON.stringify and JSON.parse
Related
I hope someone can help me out with this since when I drop a JSON test file in my rcv-folder the only result is that in the BizTalk console (in 'Running instances'), the message only states 'Queued (Awaiting processing)'. I am not sure where my issue is in the code.
I am supposed to receive a JSON which will contain some info and possibly multiple attachments (in Base64 format) and then send the mail out (with attachments in correct format, i.e. PDF, txt, xls) to a certain email-address. One of the requirements is to not use an orchestration. But I am stuck and have no idea what I am doing anymore. What makes this question different from others is that I have no orchestration in my solution. Everything will be processed in a custom send pipeline component.
The sendpipeline (in encode stage) does contain my custom component and also the MIME/SMIME encoder. I am using the SMTP-adapter.
I have created the custom pipeline component with a wizard and my initial plan was in the form below:
Receive the file (in JSON-format. It will be transformed into XML for further processing). This will all be taken care of in my rcv-pipeline and this step already works for me.
Pick out all the necessary variables from XML needed to send in the e-mail. These variables are the ones I want to show in the E-mail text. Not sure how to explain it better.
Pick out all the attachments in base64, loop through them, convert to 'regular files' and then attach them to the mail (with correct filenames, extension etc.)
The XML looks like below:
ArchiveobjectsListErrands
- ArchiveobjectErrand
* UUID (Here are the variables I need to show in the E-mail. The plain text, so to say)
- ArchiveobjectListPaper
- Attachments
* Name
* Extension
* Size
* Base64String (Base64 string which will be needed to be fetched (in GetAttachments) and then processed in (ProcessAttachments))
The code I have is below:
public Microsoft.BizTalk.Message.Interop.IBaseMessage Execute(Microsoft.BizTalk.Component.Interop.IPipelineContext pContext, Microsoft.BizTalk.Message.Interop.IBaseMessage pInMsg)
{
// 1) Read file with XPathNavigator (https://learn.microsoft.com/en-us/dotnet/standard/data/xml/extract-xml-data-using-xpathnavigator)
XPathNavigator nav = ReadXmlFromMsgBox(pInMsg);
var outMsg = pContext.GetMessageFactory().CreateMessage();
outMsg.Context = PipelineUtil.CloneMessageContext(pInMsg.Context);
// 2) Pick out the necessary vars that the registrator requires
GetRegistratorProperties(nav, pContext, outMsg);
// 3) Read attachments
var attachments = GetAttachments(pInMsg, nav);
// 4) Processa attachments
ProcessAttachments(pContext, outMsg, attachments);
// 5) Send message along for further processing in the send pipeline
return outMsg;
}
private void GetRegistratorProperties(XPathNavigator _nav, IPipelineContext _pContext, IBaseMessage _msg)
{
var bodyPart = _pContext.GetMessageFactory().CreateMessagePart();
bodyPart.ContentType = "text/application";
bodyPart.PartProperties.Write("EmailBodyText", "http://schemas.microsoft.com/BizTalk/2003/smtp-properties", "EmailBodyText.");
bodyPart.PartProperties.Write("Subject", "http://schemas.microsoft.com/BizTalk/2003/smtp-properties", "Registratorsubject - Create errand");
_msg.AddPart("Body", bodyPart, true); // True for body but false for attachments
}
private void ProcessAttachments(IPipelineContext _pContext, IBaseMessage _msg, IList<Attachment> _attachments)
{
var msgPart = _pContext.GetMessageFactory().CreateMessagePart();
//outMsg.Context = PipelineUtil.CloneMessageContext(_msg.Context);
int i = 0;
foreach (var item in _attachments)
{
msgPart.PartProperties.Write("FileName", "http://schemas.microsoft.com/BizTalk/2003/mime-properties", item.filnamn+item.extension);
msgPart.PartProperties.Write("ContentDescription", "http://schemas.microsoft.com/BizTalk/2003/mime-properties", item.contentType);
msgPart.Data = new MemoryStream(BytesFromBase64String(item.base64));
//bodyPart.Charset = "utf-8";
msgPart.ContentType = item.contentType;
//_pInMsg.AddPart("Attachment part " + i.ToString(), bodyPart, false);
_msg.AddPart("Attachment part " + i.ToString(), msgPart, false);
i++;
}
}
private IList<Attachment> GetAttachments(IBaseMessage pInMsg, XPathNavigator _nav)
{
XPathNodeIterator iterator = _nav.Select("Path to attachments in xml");
IList<Attachment> myList = new List<Attachment>();
while (iterator.MoveNext())
{
XPathNavigator node = iterator.Current;
Attachment atttachments = new Attachment();
atttachments.filenamne = node.SelectSingleNode("Name").Value;
atttachments.extension = node.SelectSingleNode("Extension").Value;
atttachments.contentType = node.SelectSingleNode("Mimetype").Value;
atttachments.base64 = node.SelectSingleNode("Base64String").Value;
myList.Add(atttachments);
}
return myList;
}
private XPathNavigator ReadXmlFromMsgBox(IBaseMessage pInMsg)
{
// Using XPathNavigator to avoid creating a XMLDoc in memory
Stream originalMessage = pInMsg.BodyPart.GetOriginalDataStream();
XPathNavigator _navigator = new XPathDocument(originalMessage).CreateNavigator();
return _navigator;
}
[Serializable]
private class FileStreamFactory : IStreamFactory
{
byte[] _data;
public FileStreamFactory(byte[] data)
{
_data = data;
}
public Stream CreateStream()
{
return new MemoryStream(_data);
}
}
private static byte[] BytesFromBase64String(string msg)
{
return Convert.FromBase64String(msg);
}
#endregion
}
I can show some example file of the XML if deemed necessary. I avoided it due to brevity and also since it is quite large.
I would greatly appreciate if anyone could help out with how the code is supposed to look to achieve what is needed, a mail with some text and attachments named correctly regarding filename and extension.
Body text and Attachments are just different segments in a MIME encoded email, usually a plain text one is the first one.
If it has a status of 'Queued (Awaiting processing)', then it sounds like either
the host instance that is expecting to process it is not in a running state. Fix: Start the host instance.
the send port is not in a Started sate. Fix: set the send port to Started
or the send port has a service window set on it. Fix: disable the service window.
I am trying to get the full contents of my modules From Zoho to our local Server. The deluge code does work as it returns to me the data which is being sent via the API. However, once it reaches the API, it is null. Any idea?
Below is the deluge code:
// Create a map that holds the values of the new contact that needs to be created
evaluation_info = Map();
evaluation_info.put("BulkData",zoho.crm.getRecords("Publishers"));
data = Map();
data.put(evaluation_info);
response = invokeurl
[
url :"https://zohoapi.xxxxx.com/publisher/publish"
type :POST
parameters:data
connection:"zohowebapi"
];
info data; (data returns all the data from publishers)
Here is my ASP.NET core restful API. It does ping it and create the file but the content of the file is null.
Route("[controller]")]
[ApiController]
public class PublisherController : ControllerBase
{
[HttpGet("[action]"), HttpPost("[action]")]
public void Publish(string data)
{
(it's already null when it comes here. why?)
string JSONresult = JsonConvert.SerializeObject(data);
string path = #"C:\storage\journalytics_evaluationsv2.json";
using (var file = new StreamWriter(path, true))
{
file.WriteLine(JSONresult.ToString());
file.Close();
}
}
}
}
What am I missing? Thank you
After contacting Zoho support, the solution he offered was to loop through the data in order to get all the contents from a module (if they are more than 200 records. With the solution provided, one doesn't really need the deluge code anymore as long as you have the ZOHO api set to your account in code. This was my final solution. This solution is not scalable at all. It's best to work with the BULK CSV.
// Our own ZohoAPI which lets us connect and authenticate etc. Yours may look slightly different
ZohoApi zohoApi = new ZohoApi();
zohoApi.Initialize();
ZCRMRestClient restClient = ZCRMRestClient.GetInstance();
var allMedicalJournals = new List<ZCRMRecord>();
for (int i = 1; i <= 30; i++)
{
List<ZCRMRecord> accountAccessRecords2 =
restClient.GetModuleInstance("Journals").SearchByCriteria("Tag:equals:MedicalSet", i, 200).BulkData.ToList();
foreach (var newData in accountAccessRecords2)
allMedicalJournals.Add(newData);
}
As part of ML automation process I want to dynamically create new AutoML model. I'm using C# (.net framework) and Google.Cloud.AutoML.V1.
After trying to run CreateDataSet code:
var autoMlClient = AutoMlClient.Create();
var parent = LocationName.FromProjectLocation(_projectId, _locationId);
var dataset = new Google.Cloud.AutoML.V1.Dataset();
dataset.DisplayName = "NewDataSet";
var response = autoMlClient.CreateDataset(parent, dataset);
I get the following error:
Field: dataset.dataset_metadata; Message: Required field not set
According to this user manual I should set Dataset Metadata Type, but the list contains only specific types of classifications (Translation/ImageClassifications etc.), I can't find a simple classification type.
How do I create a simple classification data set with the API ? in the AutoML UI its just with a simple button click ("NEW DATASET") - and have to provide only name & region - no classification type.
I also tried to set:
dataset.TextClassificationDatasetMetadata =
new TextClassificationDatasetMetadata() { ClassificationType = ClassificationType.Multiclass };
But I was unable to import data to it (got too many errors of invalid inputs from the input CSV file), I guess its related to the reason that the input format is not suitable for Text Classification.
UPDATE
I've just notice that the Nuget works with AutoML v1 but v1 beta does contains TablesDatasetMetadata Dataset Metadata Type for normal classifications. I'm speechless.
I also experienced this scenario today while creating a dataset using the NodeJS client. Since the Google AutoML table service is in the beta level you need to use the beta version of the AutoML client. In the Google cloud documentation they have used the beta client to create a dataset.
In NodeJS importing the beta version require('#google-cloud/automl').v1beta1.AutoMlClient instead of importing the normal version (v1) require('#google-cloud/automl').v1 worked for me to successfully execute the create dataset functionality.
In C# you can achieve the same through a POST request. Hope this helps :)
After #RajithaWarusavitarana comment, and my last question update , below is the code that did the trick. The token is being generated by GoogleClientAPI nuget and AutoML is handled by REST.
string GcpGlobalEndPointUrl = "https://automl.googleapis.com";
string GcpGlobalLocation = "us-central1"; // api "parent" parameter
public string GetToken(string jsonFilePath)
{
var serviceAccountCredentialFileContents = System.IO.File.ReadAllText(jsonFilePath);
var credentialParameters = NewtonsoftJsonSerializer.Instance.Deserialize<JsonCredentialParameters>(serviceAccountCredentialFileContents);
var initializer = new ServiceAccountCredential.Initializer(credentialParameters.ClientEmail)
{
Scopes = new List<string> { "https://www.googleapis.com/auth/cloud-platform" }
};
var cred = new ServiceAccountCredential(initializer.FromPrivateKey(credentialParameters.PrivateKey));
string accessToken = cred.GetAccessTokenForRequestAsync("https://oauth2.googleapis.com/token").Result;
return accessToken;
}
public void GetDataSetList(string projectId, string token)
{
var restClient = new RestClient(GcpGlobalEndPointUrl);
var createDataSetReqUrl = $"v1beta1/projects/{projectId}/locations/{GcpGlobalLocation}/datasets";
var createDataSetReq = new RestRequest(createDataSetReqUrl, Method.GET);
createDataSetReq.AddHeader("Authorization", $"Bearer {token}");
var createDatasetResponse = restClient.Execute(createDataSetReq);
createDatasetResponse.Dump();
}
I took the token generation code from google-api-dotnet-client Test File
I'm trying to connect to an SSRS server and get report data via .NET webClient. I'm doing this because I can't use forms and I don't want to just send the user to the report server. I'd rather keep everything in my web application.
So I have this bit of code in a controller:
public IHttpActionResult GetSpecs(int Id)
{
var client = new WebClient();
client.Credentials = new System.Net.NetworkCredential("username", "pw", "domain");
var data = client.DownloadString(ReportServerUrl + "?%2fFactory+Specs+Reports%2fSpecs_Stats_Matrix&rs:Command=Render&a=" + Id + "&b=" + CurrentUser.Id);
return Ok(data)
}
It successfully connects to the SSRS server, and it does get data. Inspecting the data, it looks like it's the report I need, but it's just one giant string of html and javascript that the SSRS server spits out.
My question is, is there a good way of handling this data?
I'm in unfamiliar territory, and it doesn't seem like a lot of people interact with SSRS in this way.
I'm not quite sure how to display all the data the end user.
Thanks!
Thats quite easy. :)
First you need some assemblies to access the reporting service.
All these assemblies are easy to include in your project via Nuget,
After this you need to connect to your SSRS service instance like this:
using Microsoft.Reporting.WebForms;
CustomReportCredentials reportServerCredentials = new CustomReportCredentials("User", "Password", "REPORTINGSERVER");
ServerReport report = new ServerReport()
{
ReportServerUrl = new Uri("https://reporting.xxxx.com/ReportServer"),
ReportServerCredentials = reportServerCredentials,
ReportPath = "/Reports/MyReport",
Timeout = 200000
};
Ask the service for supported render extentions and generate the report:
var renderExtentions = report.ListRenderingExtensions();
report.SetParameters(new ReportParameter[]
{
new ReportParameter("parameter1", dcStringID.ToString()),
new ReportParameter("parameter2", begin.ToString()),
new ReportParameter("parameter3", end.ToString())
});
String mineType = String.Empty;
String fileNameExtention = String.Empty;
Stream stream = report.Render(renderExtentions.First(), null, null, out mineType, out fileNameExtention);
At this point you will have all you need. Stream, mine type, file extention.
I’m trying to send an email using LOTUS NOTES with the help of “domino” dll (Programming language : C#).
I want to attach a mail signature into the body of email. I’m hoping to add a .jpg for the signature. I also have other email body formatting. Hence I have decided to use HTML for styling and attaching the signature. After browsing the web found out that in NotesRichTextStyle there is a property PassThruHTML. The legal values that can be given for it as per this link are (-1), (0), (255).
The ISSUE is that when I set (-1) the app popup a message saying that “Style value must be True, False, or STYLE_NO_CHANGE (YES, NO, or MAYBE for Java)”.
But in c sharp code it accepts only int values but not the values given in the popup.
Following is the C# code for the answer given by Ken Pespisa's reference link.
NotesSession LNSession = new NotesSession();
NotesDatabase LNDatabase = null;
NotesDocument LNDocument;
NotesMIMEEntity LNBody;
NotesStream LNStream;
NotesMIMEHeader LNHeader;
try
{
LNSession.Initialize(txtPassword.Text);
LNDatabase = LNSession.GetDatabase(txtServer.Text, txtUserName.Text, false);
LNStream = LNSession.CreateStream();
LNSession.ConvertMime = false;
//Create an email
LNDocument = LNDatabase.CreateDocument();
LNDocument.ReplaceItemValue("Form", "Memo");
LNBody = LNDocument.CreateMIMEEntity();
LNHeader = LNBody.CreateHeader("Subject");
LNHeader.SetHeaderVal("Add your subject here");
LNHeader = LNBody.CreateHeader("To");
LNHeader.SetHeaderVal("Give your recipient email address");
LNStream.WriteText("<html>");
LNStream.WriteText("<body bgcolor=\"blue\" text=\"white\">");
LNStream.WriteText("<table border=\"2\">");
LNStream.WriteText("<tr>");
LNStream.WriteText("<td>Hello World!</td>");
LNStream.WriteText("</tr>");
LNStream.WriteText("</table>");
LNStream.WriteText("</body>");
LNStream.WriteText("</html>");
LNBody.SetContentFromText(LNStream, "text/HTML;charset=UTF-8", MIME_ENCODING.ENC_IDENTITY_7BIT);
LNDocument.Send(false);
}
catch (Exception e)
{
MessageBox.Show(e.Message);
}
If you're just sending email you should look at the NotesMimeEntity classes, and review this website for examples: http://www-01.ibm.com/support/docview.wss?uid=swg21098323
PassThruHTML won't help you much unless you're trying to display custom HTML in a browser when viewing a Notes document or form via Domino.