JSON.NET Argument Exception when creating JSON with LINQ - linq

I'm using JSON.NET Linq to JSON, when I execute the below I get the following argument exception:
Can not add Newtonsoft.Json.Linq.JValue to Newtonsoft.Json.Linq.JObject
What's wrong with the code
string content = new JObject(
new JObject("auth",
new JProperty("user", "anemail#gmail.com"),
new JProperty("secret", "somepassword")
),
new JObject("config",
new JProperty("template", "1")
),
new JObject("data",
new JProperty("email", "body")
)
).ToString();

As per the JSON.NET documentation, you need to wrap your JObjects in JProperties themselves:
string content = new JObject(
new JProperty("auth",
new JObject(
new JProperty("user", "anemail#gmail.com"),
new JProperty("secret", "somepassword")
)
),
new JProperty("config",
new JObject(
new JProperty("template", "1")
)
),
new JProperty("data",
new JObject(
new JProperty("email", "body")
)
)
).ToString();

Related

Web url cannot be empty for url type button

var msg = context.MakeMessage();
msg.Attachments = new List<Attachment>();
SigninCard card = new SigninCard()
{
Text= "link it",
Buttons = new List<CardAction>
{
new CardAction
{
Value = "account linking url https",
Type = "account_link",
Title = "Link"
},
}
};
msg.Attachments.Add(card.ToAttachment());
await context.PostAsync(msg);
I'm trying to use SignInCard to link Facebook account.
This error appears:
{"error":{"message":"(#100) Web url cannot be empty for url type
button","type":"OAuthException","code":100,"error_subcode":2018041,"fbtrace_id":"GclYUUuTL2D"}}
But there is a string https url in url field.
Any idea ?
I figured this out.
var msg = context.MakeMessage();
dynamic messageData = new JObject();
messageData.attachment = new JObject();
messageData.attachment.type = "template";
messageData.attachment.payload = new JObject();
messageData.attachment.payload.template_type = "generic";
messageData.attachment.payload.elements
= new JArray(
new JObject(
new JProperty("title", "title"),
new JProperty("subtitle", "Link your account"),
new JProperty("buttons",
new JArray(
new JObject(
new JProperty("type", "account_link"),
new JProperty("url", "yourUrl")
)
)
)
)
);
msg.ChannelData = messageData;
await context.PostAsync(msg);
You don't have to get into channel-specific ChannelData. In your SigninCard's Buttons initializer, instead of
Type = "account_link",
use
Type = ActionTypes.Signin,
Worked on my Facebook Messenger channel.

How to retrieve values by index from a dynamic Object

String zohoResponse = #"
[
{
'Title':'Mr.',
'First Name':'ram',
'Last Name':'chang',
'Employed at Trade Client Name':'mile travel',
'Telephone':'657498333',
'E-mail':'abc#traveller.com',
'Fax':' ',
'Street':'123 Street',
'City':'Winnipeg',
'State / Province':'Manitoba',
'Country':'Canada',
'Postcode':'R4T 600',
'Agent ID':70,
'Primary Sales Agent':' ',
'Employed at From':'09/12/2008',
'Employed at To':'09/12/2028'
}
]
";
dynamic jsonObj = JsonConvert.DeserializeObject(zohoResponse);
xmlData = new XDocument(
`enter code here` new XElement("Leads",
new XElement("row", new XAttribute("no", "1"),
new XElement("FL", new XAttribute("val", "Lead Source"), jsonObj["Last Name"]),
new XElement("FL", new XAttribute("val", "Title"), jsonObj["First Name"])
)));
I want to retrieve the dynamic index values. i have used new
XElement("FL", new XAttribute("val", "Title"),
jsonObj.GetType().GetProperty("Title").GetValue(jsonObj,null))
but am still getting exception on retrieve the values by index
jsonObj is an array so you need to reach the first element in the array first before querying the json literal.
dynamic jsonObj = JsonConvert.DeserializeObject(zohoResponse);
dynamic arr = jsonObj.First;
var xmlData = new XDocument(
new XElement("Leads",
new XElement("row", new XAttribute("no", "1"),
new XElement("FL", new XAttribute("val", "Lead Source"), arr["Last Name"]),
new XElement("FL", new XAttribute("val", "Title"), arr["First Name"])
)));

An error when serializing a list of validationattribute

I am trying to serialize a list of (ValidationAttribute) as shown below:
RequiredAttribute tRequired = new RequiredAttribute();
List<ValidationAttribute> ValidationList = new List<ValidationAttribute>();
ValidationList.Add(tRequired);
XmlSerializer tXMLSerializer = new XmlSerializer(typeof(List<ValidationAttribute>));
MemoryStream tMemStream = new MemoryStream();
StreamWriter tStreamWriter = new StreamWriter(tMemStream);
tXMLSerializer.Serialize(tStreamWriter, ValidationList);
When the (Serialize) function execute, the following exception will be thrown:
The type System.ComponentModel.DataAnnotations.RequiredAttribute was not expected. Use the XmlInclude or SoapInclude attribute to specify types that are not known statically
I have figured it out. I needed to pass the type of (RequiredAttribute) to the XMLSerializer:
RequiredAttribute tRequired = new RequiredAttribute();
List<ValidationAttribute> ValidationList = new List<ValidationAttribute>();
ValidationList.Add(tRequired);
Type[] tExtraTypes = new Type[] { typeof(RequiredAttribute) };
XmlSerializer tXMLSerializer = new XmlSerializer(typeof(List<ValidationAttribute>),tExtraTypes );

How can I create a MetadataWorkspace using metadata loading delegates?

I followed this example Changing schema name on runtime - Entity Framework where I can create a new EntityConnection from a MetaDataWorkspace that I then use to construct a DbContext with a different schema, but I get compiler warnings saying that RegisterItemCollection method is obsolete and to "Construct MetadataWorkspace using constructor that accepts metadata loading delegates."
How do I do that? Here is the code that is working but gives the 3 warnings for the RegsiterItemCollection calls. I'm surprised it works since warning says obsolete not just deprecated.
public static EntityConnection CreateEntityConnection(string schema, string connString, string model)
{
XmlReader[] conceptualReader = new XmlReader[]
{
XmlReader.Create(
Assembly
.GetExecutingAssembly()
.GetManifestResourceStream(model + ".csdl")
)
};
XmlReader[] mappingReader = new XmlReader[]
{
XmlReader.Create(
Assembly
.GetExecutingAssembly()
.GetManifestResourceStream(model + ".msl")
)
};
var storageReader = XmlReader.Create(
Assembly
.GetExecutingAssembly()
.GetManifestResourceStream(model + ".ssdl")
);
//XNamespace storageNS = "http://schemas.microsoft.com/ado/2009/02/edm/ssdl"; // this would not work!!!
XNamespace storageNS = "http://schemas.microsoft.com/ado/2009/11/edm/ssdl";
var storageXml = XElement.Load(storageReader);
foreach (var entitySet in storageXml.Descendants(storageNS + "EntitySet"))
{
var schemaAttribute = entitySet.Attributes("Schema").FirstOrDefault();
if (schemaAttribute != null)
{
schemaAttribute.SetValue(schema);
}
}
storageXml.CreateReader();
StoreItemCollection storageCollection =
new StoreItemCollection(
new XmlReader[] { storageXml.CreateReader() }
);
EdmItemCollection conceptualCollection = new EdmItemCollection(conceptualReader);
StorageMappingItemCollection mappingCollection =
new StorageMappingItemCollection(
conceptualCollection, storageCollection, mappingReader
);
//var workspace2 = new MetadataWorkspace(conceptualCollection, storageCollection, mappingCollection);
var workspace = new MetadataWorkspace();
workspace.RegisterItemCollection(conceptualCollection);
workspace.RegisterItemCollection(storageCollection);
workspace.RegisterItemCollection(mappingCollection);
var connectionData = new EntityConnectionStringBuilder(connString);
var connection = DbProviderFactories
.GetFactory(connectionData.Provider)
.CreateConnection();
connection.ConnectionString = connectionData.ProviderConnectionString;
return new EntityConnection(workspace, connection);
}
I was able to get rid of the 3 warning messages. Basically it wants you to register the collections in the constructor of the MetadataWorkspace.
There are 3 different overloads for MetadataWorkspace, I chose to use the one which requires to to supply a path (array of strings) to the workspace metadata. To do this I saved readers to temp files and reloaded them.
This is working for me without any warnings.
public static EntityConnection CreateEntityConnection(string schema, string connString, string model) {
var conceptualReader = XmlReader.Create(Assembly.GetExecutingAssembly().GetManifestResourceStream(model + ".csdl"));
var mappingReader = XmlReader.Create(Assembly.GetExecutingAssembly().GetManifestResourceStream(model + ".msl"));
var storageReader = XmlReader.Create(Assembly.GetExecutingAssembly().GetManifestResourceStream(model + ".ssdl"));
XNamespace storageNS = "http://schemas.microsoft.com/ado/2009/11/edm/ssdl";
var storageXml = XElement.Load(storageReader);
var conceptualXml = XElement.Load(conceptualReader);
var mappingXml = XElement.Load(mappingReader);
foreach (var entitySet in storageXml.Descendants(storageNS + "EntitySet")) {
var schemaAttribute = entitySet.Attributes("Schema").FirstOrDefault();
if (schemaAttribute != null) {
schemaAttribute.SetValue(schema);
}
}
storageXml.Save("temp.ssdl");
conceptualXml.Save("temp.csdl");
mappingXml.Save("temp.msl");
MetadataWorkspace workspace = new MetadataWorkspace(new List<String>(){
#"temp.csdl",
#"temp.ssdl",
#"temp.msl"
}
, new List<Assembly>());
var connectionData = new EntityConnectionStringBuilder(connString);
var connection = DbProviderFactories.GetFactory(connectionData.Provider).CreateConnection();
connection.ConnectionString = connectionData.ProviderConnectionString;
return new EntityConnection(workspace, connection);
}
Not wanting to create temp files which slows the process down, I found an alternate answer to this is fairly simple. I replaced these lines of code -
//var workspace2 = new MetadataWorkspace(conceptualCollection, storageCollection, mappingCollection);
var workspace = new MetadataWorkspace();
workspace.RegisterItemCollection(conceptualCollection);
workspace.RegisterItemCollection(storageCollection);
workspace.RegisterItemCollection(mappingCollection);
with this one line of code -
var workspace = new MetadataWorkspace(() => conceptualCollection, () => storageCollection, () => mappingCollection);
and that works fine.

How to convert a data table to a list of strongly typed objects in C# using LINQ?

I am doing a WPF Application written with C# code, My problem is I need to convert a data table from a dataset but sadly it throws me the exception "Cannot convert lambda expression to type 'string' because it is not a delegate type" can you guys please help me with this.(I had the code which throws me the exception)
SqlDataAdapter da = new SqlDataAdapter(commBuildingSelector);
DataSet ds = new DataSet();
da.Fill(ds);
DataTable myTable = ds.Tables[0];
List<Building> buildings = new List<Building>();
buildings = (from bl in myTable
select new Building()
{
BuildingID = bl.BuildingID,
BuildingName = bl.BuildingName,
isActive = bl.isActive,
LastEditDate = bl.LastEditDate,
LastEditUser = bl.LastEditUser
}).ToList();
return new List<Building>();
Use AsEnumerable and Field<T>:
buildings = (from bl in myTable.AsEnumerable()
select new Building()
{
BuildingID = bl.Field<int>("BuildingID")
// etc
}).ToList();

Resources