I made a drag-and-drop workflow, and got an Literal error while passing an object through the INargument. Any ideas how I can get around this error?
error: 'Literal': Literal only supports value types and the immutable type System.String. The type System.Object cannot be used as a literal.
I've seen some answers, but all the examples are in hard-coded workflows, and I don't want rewrite the whole workflow in hard-code.
WorkflowActivitycheckdb ActEmail = new WorkflowActivitycheckdb {
EmailList = AdminsToList,
EmailContent = tolist,
UserName = name,
UnApprovedS = UnApproved,
NumberOfUsers = tel,
NumberOfAdmins = tel2
};
WorkflowInvoker.Invoke(ActEmail);
please help.
WorkflowActivitycheckdb ActEmail = new WorkflowActivitycheckdb {
EmailList = new InArgument<Whateveryourobjectis>( x=> AdminsToList),
EmailContent = tolist,
UserName = name,
UnApprovedS = UnApproved,
NumberOfUsers = tel,
NumberOfAdmins = tel2
};
WorkflowInvoker.Invoke(ActEmail);
gl
You could try writing that particular line outside the object initializer.
Eg :
ActEmail.EmailList = AdminsToList;
Make the EmailList class immutable.
Related
I am trying to find a specific string in a property of a class and replace it with another string if found. I tried various methods using Linq but I am not able to replace it. In debug mode, when I monitor the object again, the replace command hasn't worked. Please help. Including a sample example below.
class Tryreplace
{
public string ClubName { get; set; }
}
List<Tryreplace> tryreplaces = new List<Tryreplace>();
Tryreplace tryreplace = new Tryreplace { ClubName = "Manchester United FC" };
Tryreplace tryreplace2 = new Tryreplace { ClubName = "Arsenal FC" };
tryreplaces.Add(tryreplace);
tryreplaces.Add(tryreplace2);
Tried 2 ways below, both didn't work...
tryreplaces.ForEach(x => x.ClubName.Replace("Manchester", "Newcastle"));
List<Tryreplace> tryreplaces2 = tryreplaces.Select(x => { x.ClubName.Replace("Manchester", "Newcastle"); return x; }).ToList();
After both, I only see Manchester and not Newcastle.
I would like to see replaced string Newcastle in the objects and not Manchester. Please help!
Have an look at the official Documentation from the String.Replace() Method:
Returns a new string in which all occurrences of a specified string in
the current instance are replaced with another specified string.
So you will need to set the property as shown in the Example:
tryreplaces.ForEach(x => x.ClubName = x.ClubName.Replace("Manchester", "Newcastle"))
String.Replace() Docs from Microsoft
in C# (or most language) string are immutable, mean whenever you are making change to it, it will create another instance of string, but it will not change self variable itself.
Or simply if you want to replace part of the string you need to assign make to original variable.
string name = "Amyn";
name.Replace("A", "#");
Console.WriteLine(name); // it will be still Amyn
name = name.Replace("A", "#"); // its right way
Console.WriteLine(name); // it will display "#myn"
so in your code also you need to assign the variable back.
tryreplaces.ForEach(x => x.ClubName = x.ClubName.Replace("Manchester", "Newcastle"))
Follow Code C#:
var body = new CustomerRequest
{
Method = "CREDIT_CARD",
CreditCard = new Creditcard
{
ExpirationMonth = "06",
ExpirationYear = "2022",
Number = "4012001037141112",
Cvc = "123"
}
};
I'm new to F#, I can not instantiate classes like C#, See the code below in F#:
let body = CustomerRequest
(
Method = "CREDIT_CARD" // Help here
)
I can not convert C # to F #
If you are doing idiomatic F# you would model this with Records instead of classes.
You could do it like this:
type CreditCard = {
ExpirationMonth: int;
//More
}
type CustomerRequest = {
Method: string;
CreditCard: CreditCard;
}
let req = {
Method = "Credit"
CreditCard = {
ExpirationMonth = 6
//More
}
}
The compiler has type-inference that means it can guess that req is a CustomerRequest by the fields you have in it, and the same for the CreditCard - you can hint the type if you really need to.
If you really are after classes - perhaps you have to interop with C# code, then you would do it like this:
type CreditCard2(expirationMonth:int) =
member this.ExpirationMonth = expirationMonth
type CustomerRequest2(method: string, creditCard: CreditCard2) =
member this.Method = method
member this.CreditCard = creditCard
let req2 = CustomerRequest2 ("Credit", CreditCard2 (5))
If you just want to use named arguments to set properties of the classes you are constructing: the syntax is quite similar to C#. As for the level of indentation, you need to align with that of the first argument.
let body =
CustomerRequest(
Method = "CREDIT_CARD",
CreditCard =
Creditcard(
ExpirationMonth = "06",
ExpirationYear = "2022",
Number = "4012001037141112",
Cvc = "123" ) )
I think this is what you are looking for:
CreditCard.fs
namespace StackOverflow
type CreditCard() =
member val ExpirationDate = "" with get, set
member val ExpirationYear = "" with get, set
member val Number = "" with get, set
member val Cvc = "" with get, set
type CustomerRequest() =
member val Method = "" with get, set
member val CreditCard = new CreditCard() with get, set
Program.fs
open System
open StackOverflow
[<EntryPoint>]
let main argv =
let body = new CustomerRequest(Method = "CREDIT_CARD",
CreditCard = CreditCard(
ExpirationDate = "06",
ExpirationYear = "2022",
Number = "4012001037141112",
Cvc = "123"
))
0
I do not know much about F# so maybe using Records like David Shaw uses is better design wise. But basically this will let you do it without a parameter constructor and without a mutable non property value in your type.
I am trying to add an object to my Algolia database using a slightly different structure provided by the documentation so that I don't have to type out the Json object in string format, however I ran into an error stating
Cannot implicitly convert anonymous type to
System.Collections.Generic.List
I see the red error message for all of the key/values in the objs variable.
var songIndexHelper = HttpContext.Application.Get("SongIndexHelper") as IndexHelper<SongAlgoliaModel>;
List<JObject> objs = new List<JObject>();
objs = new
{
ApprovalFL = false,
FreeFL = album.FreeFL,
LicenseFL = album.LicenseFL,
AccountInfoID = album.AccountInfoID,
AlbumID = album.AlbumID,
SongID = song.SongID,
BPM = song.BPM,
AccountImageURL = album.AccountInfo.ImageURL,
AccountType = "Artist",
AlbumName = album.AlbumName,
Artist = artist,
FeaturedArtist = songArtistsList,
ImageURL = album.ImageURL,
iTunesURL = album.iTunesURL,
LabelName = album.LabelName,
Title = album.AlbumName,
UserID = album.AccountInfo.UserID,
UploadDate = song.UploadDate,
Duration = song.Duration,
objectID = song.SongID
};
songIndexHelper.AddObjects(objs);
Here's the reference to documentation: https://www.algolia.com/doc/api-reference/api-methods/add-objects/
Edit alternative method however, my formatting of LicenseFL is off
List<JObject> objs = new List<JObject>();
objs.Add(JObject.Parse(#"{""ApprovalFL"":false, ""FreeFL"":" + album.FreeFL + ",""LicenseFL"":" +album.LicenseFL+ "}"));
songIndexHelper.AddObjects(objs);
The Algolia docs are unfortunately focused on the use of JObject (and JSON strings) which makes it reasonably easy to make mistakes (e.g. invalid JSON).
This is an approach you might like to consider:
var anon = new
{
ApprovalFL = true,
// Any other properties here
objectID = song.SongID
};
var obj = JObject.FromObject(anon);
var objs = new List<JObject> { obj };
songIndexHelper.AddObjects(objs);
Now you get some level of safety due to the anon variable (e.g. don't have to worry about invalid JSON strings) but also easy interaction with the Algolia API (which is documented in terms of JObject).
This is my first question here.
I want to know the syntax to insert a new notes document in the lotus notes database if it is not existing using c#.
I have a code in vb script bit I do not know about vb script and lotus notes.
set doc = vw.GetDocumentByKey(empno)
if doc is nothing then
set doc = db.CreateDocument
doc.Form = "EmployeeRepository"
doc.Employno = empno
doc.FirstName = fname
doc.LastName = lname
doc.Group = grp
doc.Department = dept
doc.officeemailaddress = officemail
doc.officegeneralline = officegenline
doc.designation = desig
doc.officeaddress = officeadd
else
doc.FirstName = fname
doc.LastName = lname
doc.Group = grp
doc.Department = dept
doc.officeemailaddress = officemail
doc.officegeneralline = officegenline
doc.designation = desig
doc.officeaddress = officeadd
end if
call doc.save(true, true)
How can I achieve this in c#?
The C# syntax for the if statement is different. Instead of this:
if doc is nothing then
...
else
...
end if
You will need
if (doc != null)
{
...
}
else
{
...
}
Also, the C# language does not support shorthand notation doc.item = X. So the assignments in that format in the above code need to be changed to use the ReplaceItemValue method. I.e., instead of this:
doc.Form = "EmployeeRepository"
doc.Employno = empno
doc.FirstName = fname
doc.LastName = lname
you need to use this:
doc.ReplaceItemValue("Form","EmployeeRepository");
doc.ReplaceItemValue("Employno",empno);
doc.ReplaceItemValue("FirstName", fname);
doc.ReplaceItemValue("LastName", lname);
I might also suggest trying an ExpandoObject (although I haven't tried that yet, but I'm about to give it a go). It's a dynamic type so you have to be careful with how you create it, but you could keep adding additional properties to it without having to instantiate them directly:
dynamic noteDocument = new System.Dynamic.ExpandoObject();
noteDocument.ShortName = "wonkaWillie";
noteDocument.Comment = "No Comment";
noteDocument.MailSystem = "Other";
noteDocument.PowerLevel = "It's over NINE THOUSAND!!!!!";
I suppose you could just as easily (and probably be a little tighter of a solution) to have a pre-formatted class ready for the occasion of adding data into a specific document format too though.
So the ExpandoObject method works, but using a class with explicitly declared fields / properties is much cleaner....you can pass in an instance of a class to a method that performs this pretty handily:
class NotesDocumentItemClass
{
public string Form {get; set;} = "Person";
public string FullName {get; set;} = "Over 9000/Notes/Address/Or/Whatever";
}
and then pass an instance of that class into a method like.....
private bool AddEntry(NotesDatabase db, NoteDocumentItemClass d)
{
NotesDocument newDoc = db.CreateDocument();
doc.ReplaceItemValue("Form", d.Person);
doc.ReplaceItemValue("FullName", d.FullName);
return newDoc.Save();
}
while writing the question subject I came across
some other allmost related post ...leading to MSDN
http://msdn.microsoft.com/en-us/library/system.reflection.parameterinfo.aspx
but i couldn't manage to extract the bit of code i needed
i just learnd how to get method name with a helper method based on st and sf as following :
public void setLogView(View ViewMode)
{
AAdToAppLog();
Lview_AH_AutomationLog.Sorting = SortOrder.Ascending;
ColumnHeader ColHeadRowNo = new ColumnHeader();
ColumnHeader ColHeadFunction = new ColumnHeader();
ColumnHeader ColHeadContent = new ColumnHeader();
ColumnHeader ColHeadTime = new ColumnHeader();
Lview_AH_AutomationLog.View = ViewMode;
Lview_AH_AutomationLog.Columns.Add(ColHeadRowNo);
Lview_AH_AutomationLog.Columns.Add(ColHeadFunction);
Lview_AH_AutomationLog.Columns.Add(ColHeadContent);
Lview_AH_AutomationLog.Columns.Add(ColHeadTime);
ColHeadRowNo.Text = "#";
ColHeadFunction.Text = "Function Name";
ColHeadContent.Text = "Content";
ColHeadTime.Text = "Time";
ColHeadRowNo.Width = 45;
ColHeadFunction.Width = 150;
ColHeadContent.Width = 150;
ColHeadTime.Width = 100;
}
public void AAdToAppLog(string FunctionOutPut = "N/A")
{
string t = DateTime.Now.ToString("mm:ss.ff");
string h = DateTime.Now.ToString("HH");
ListViewItem FirstCell= new ListViewItem();
FirstCell.Text =h+":" +pre0Tosingle_9(LogCounter.ToString());//Another helper puts 0 infront <=9 digits
Lview_AH_AutomationLog.Items.Insert(0, FirstCell);
StackTrace st = new StackTrace();
StackFrame sf = st.GetFrame(1);
string FunctionName = sf.GetMethod().ToString().Replace("Void", "").Replace("System.Windows.Forms.", "");
FirstCell.SubItems.Add(FunctionName);
FirstCell.SubItems.Add(FunctionOutPut);
FirstCell.SubItems.Add(t);
LogCounter++;
}
so in every method i want i just put the
AddToAppLog()
that method contains my call to AddToAppLog() and then reports(Via ListView) the name of method and i just added the time of the call.
there's two things i would like to address in this post , about my implementation of that helper metod :
the "FunctionName" i recive from sf.GetMethod is nice that it throws the type of the Parameter of a given Method i liked the idea , only that it is containing parameter.type's Father + Grandfather + Great-Grandfather, but i would like only the bottom Type :
System.Windows.Forms.View
this is one of the shortest (: and i tried to get to View by it self via playing with .Replace()
so is there anothere way to strip it down or actually another method in same family that extract it the way i mentiond above or i could use a list containing every possible most-used types and do a foreach with stringReplace?
and more importently , how do i get the Method(parameterName) as well ?
thanks alot in advance !!
can someone Show An easy to comprehend , Simple syntax Example
of getting parameters name ?
The crux of this is the line that involves sf.GetMethod(); if you instead store that:
var method = sf.GetMethod();
string name = method.Name;
var parameters = method.GetParameters();
you have access to the full signature, and note that the .Name is just the simple name - not the full declaring type-name, etc. You can of course access method.DeclaringType.Name if you want more context. Note that you can only get the declaration of the parameters; you can't get their values via any normal mechanism.
However!!! I will also observe that all this has a performance cost associated with reflection and stack-walking. If you have the C# 5 compiler, you may prefer:
public void AAdToAppLog([CallerMemberName] string callerName = "")
{ ... }
which means that the compiler will supply the name of the caller voluntarily (as a constant geneated in the IL) - no need to either supply it, or go walking the stack to figure it out. You cannot, however, get the parameters like this.