how to get dynamic value using string instead of key? - c#

I have a Web API controller looking similar to this:
public void Post([FromBody]dynamic postData)
{
foreach (var row in postData)
{
var email = row.email.Value; // ok
var eventType = row.event.Value; // cannot use because "event" is reserved by .NET, C# or whatever
}
}
I'm getting a JSON from external system which contains this "event" property (outside of my control), that I'm unable to retrieve. I've tried dozens of workaround, but none of them seemed to work in this scenario. Hopefully there is some easy way of retrieving it.
The best bet I had was using reflection like:
row.GetType().GetProperty("event").GetValue(row, null);
But didn't work as I had expected. Is there something else I can try?

Solution is to use "#" like:
row.#event.Value

Related

How to check if a tweet was sent with tweetinvi [duplicate]

I am relatively new to programming in C# (Learning on my own for a school project) and decided to try using TweetInvi to implement Twitter functionality.
So far it's going good, got the authentication and publishing up and running, but I'm struggling to find out how to use the DestroyTweet() method.
It, and many other methods takes a tweetID parameter, which I can't figure out of how to find for a specific tweet.
Using the following code to publish a tweet, how can i find the tweetID of this tweet?
public ITweet publishTweet(string text)
{
return Tweet.PublishTweet(text);
}
// Snippet from a test method in main class.
twitter.twitterUser.publishTweet(System.Console.ReadLine());
// Still working on GUI so using ReadLine for now.
It's probably an easy solution, but I just can't figure it out!
Thanks in advance.
You can try something like this:
public string PublishTweet(string text)
{
var appCredentials = new TwitterCredentials(_apiKey,_apiSecret, _accessToken, _accessTokenSecret);
Tweetinvi.Auth.SetCredentials(appCredentials);
text = "my tweet";
var publishedTweet = Tweetinvi.Tweet.PublishTweet(text);
var tweetId = publishedTweet.Id.ToString();
return tweetId;
}
You just need to get the published tweet into a var for the result of the PublishTweet() method then you select the field(s) you need.
Simple solution. As explained before you need to take the tweet back from PublishTweet.
string text = "text";
ITweet tweet = Tweet.PublishTweet(text);
bool destroySuccess = tweet.Destroy();

How can I load only specific elements in AngleSharp?

I'm using AngleSharp to parse HTML5 at the moment what I'm doing is wrapping the elements I want to parse with a little bit of HTML to make it a valid HTML5 and then use the parser on that, is there a better of doing it? meaning, parsing specific elements directly and validate that the structure is indeed HTML5?
Hm, a little example would be nice. But AngleSharp does support fragment parsing, which sounds like the thing you want. In general fragment parsing is also applied when you set properties like InnerHtml, which transform strings to DOM nodes.
You can use the ParseFragment method of the HtmlParser class to get a list of nodes contained in the given source code. An example:
using AngleSharp.Parser.Html;
// ...
var source = "<div><span class=emphasized>Works!</span></div>";
var parser = new HtmlParser();
var nodes = parser.ParseFragment(source, null);//null = no context given
if (nodes.Length == 0)
Debug.WriteLine("Apparently something bad happened...");
foreach (var node in nodes)
{
// Examine the node
}
Usually all nodes will be IText or IElement types. Also comments (IComment) are possible. You will never see IDocument or IDocumentFragment nodes attached to such an INodeList. However, since HTML5 is quite robust it is very likely that you will never experience "errors" using this method.
What you can do is to look for (parsing) errors. You need to provide an IConfiguration that exposes an event aggregator, which collects such events. The simplest implementation for aggregating only such events (without possibility of adding / removing multiple handlers) is the following:
using AngleSharp.Events;
// ...
class SimpleEventAggregator : IEventAggregator
{
readonly List<HtmlParseErrorEvent> _errors = new List<HtmlParseErrorEvent>();
public void Publish<TEvent>(TEvent data)
{
var error = data as HtmlParseErrorEvent;
if (error != null)
_errors.Add(error);
}
public List<HtmlParseErrorEvent> Errors
{
get { return _errors; }
}
public void Subscribe<TEvent>(ISubscriber<TEvent> listener) { }
public void Unsubscribe<TEvent>(ISubscriber<TEvent> listener) { }
}
The simplest way to use the event aggregator with a configuration is to instantiate a new (provided) Configuration. Here as a sample snippet.
using AngleSharp;
// ...
var errorEvents = new SimpleEventAggregator();
var config = new Configuration(events: errorEvents);
Please note: Every error that is reported is an "official" error (according to W3C spec.). These errors do not indicate that the provided code is malicious or invalid, just that something is not following the spec and that a fallback had to be applied.
Hope this answers your question. If not, then please let me know.
Update Updated the answer for the latest version of AngleSharp.

CRM 2011 - How to set data in records from subgrid in Entity using C# code

I am making a plugin in CRM 2011. The plugin is taking data from the Entity's subgrid by using fetchXML, making some calculate with the data and at the end of the plugin I want to set the new calculated data back in the subgrid, but I can't ...
I tried few ways to do that like:
(1)
private static OptionSetValue CreateOptionSet(int optionSetValue)
{
OptionSetValue optionSetInstance = new OptionSetValue();
optionSetInstance.Value = optionSetValue;
return optionSetInstance;
}
(2)
public void setVal(Entity entity, string attr, object val)
{
if (entity.Attributes.Contains(attr))
{
entity[attr] = val;
}
else
{
entity.Attributes.Add(attr, val);
}
}
and just
paid["zbg_paidamount"] = 400;
payment.Attributes["zbg_suggestedamount"] = paidVal;
But nothing works...
I am thinking maybe is from the type of the data that I am trying to set but not sure.
Please if you can help me I am desperate.
Thanks
Even though it looks like you've resolved your issue each section of your code has an issue with it...
(1) - Use the int Constructor for OptionSetValue:
(2) - don't worry about checking the value existing or not, just set it directly on the entity (also don't worry about accessing the Attributes collection)
payment["zbg_paidamount"] = new OptionSetValue(400);
In Response to Draiden's Comments
The indexer on the Entity class will automatically handle adding or updating a value. Here is an example LinqPad program:

Extracting a key-value pair from a web service XML response

I'm working with C# and the .NET 2.0 framework in Visual Studio 2010.
I'm trying to extract a URL which is returned by a web service.
This URL is returned in an array of features containing keys and values. (I think this is similar to what I learned in school is called a hash table).
My intellisense doesn't pick up anything useful and I can't figure out what I'm doing wrong.
This is the code. What goes in serverInfo.FeatureSet[]?
public string wfl_reqURL(string username, string password)
{
MyWorkflow.ServerInfo serverInfo = new MyWorkflow.ServerInfo();
myURL = serverInfo.FeatureSet[];
}
This is how it's described in the WSDL. FeatureSet is being returned as an array with a string key and a string value:
<ServerInfo>
<FeatureSet>
<Feature>
<Key>FileUploadUrl</Key>
<Value>http://localhost/transferindex.php</Value>
</Feature>
</FeatureSet>
</ServerInfo>
Have I provided enough detail about my problem? Most of the information I've found seems to be about how to create such arrays in web services, not select one from a web service as I'd like to do.
Try something like this:
object neededItem = null;
foreach (string item in serverInfo.FeatureSet.Keys)
{
if (item == "FileUploadUrl")
{
neededItem = serverInfo.FeatureSet[item];
break;
}
}
if (neededItem != null)
{
//Do something
}
If you're using c# 3.5 then something in linq like
myURL = serverInfo.FeatureSet.First(o=>o.Key == "FileUploadUrl").Value
The problem was in the data type. Changing the code to this solved the problem, albeit in a messy way. I thought it had something to do with types and how it was defined...either as dictionary or arrays, but it was a bit different than I'd thought...
foreach( MyWorkFlow.Feature feature in serverInfo.FeatureSet) {
if (feature.Key.ToString() == "FileUploadUrl") {
string myURL = feature.Value;
Console.WriteLine(myURL);
}

Calling javascript object method using WebBrowser.Document.InvokeScript

In my WinForms application I need to call javascript function from my WebBrowser control. I used Document.InvokeScript and it works perfect with functions alone e.g
Document.InvokeScript("function").
But when i want to call javascript object method e.g.
Document.InvokeScript("obj.method")
it doesn't work. Is there a way to make it work? Or different solution to this problem? Without changing anything in the javascript code!
Thanks in advance :)
The example in the documentation does NOT include the parenthesis.
private void InvokeScript()
{
if (webBrowser1.Document != null)
{
HtmlDocument doc = webBrowser1.Document;
String str = doc.InvokeScript("test").ToString() ;
Object jscriptObj = doc.InvokeScript("testJScriptObject");
Object domOb = doc.InvokeScript("testElement");
}
}
Try
Document.InvokeMethod("obj.method");
Note that you can pass arguments if you use HtmlDocument.InvokeScript Method (String, Object[]).
Edit
Looks like you aren't the only one with this issue: HtmlDocument.InvokeScript - Calling a method of an object . You can make a "Proxy function" like the poster of that link suggests. Basically you have a function that invokes your object's function. It's not an ideal solution, but it'll definitely work. I'll continue looking to see if this is possible.
Another post on same issue: Using WebBrowser.Document.InvokeScript() to mess around with foreign JavaScript . Interesting solution proposed by C. Groß on CodeProject:
private string sendJS(string JScript) {
object[] args = {JScript};
return webBrowser1.Document.InvokeScript("eval",args).ToString();
}
You could make that an extension method on HtmlDocument and call that to run your function, only using this new function you WOULD include parenthesis, arguments, the whole nine yards in the string you pass in (since it is just passed along to an eval).
Looks like HtmlDocument does not have support for calling methods on existing objects. Only global functions. :(
Unfortunately you can't call object methods out of the box using WebBrowser.Document.InvokeScript.
The solution is to provide a global function on the JavaScript side which can redirect your call. In the most simplistic form this would look like:
function invoke(method, args) {
// The root context is assumed to be the window object. The last part of the method parameter is the actual function name.
var context = window;
var namespace = method.split('.');
var func = namespace.pop();
// Resolve the context
for (var i = 0; i < namespace.length; i++) {
context = context[namespace[i]];
}
// Invoke the target function.
result = context[func].apply(context, args);
}
In your .NET code you would use this as follows:
var parameters = new object[] { "obj.method", yourArgument };
var resultJson = WebBrowser.Document.InvokeScript("invoke", parameters);
As you mention that you cannot change anything to your existing JavaScript code, you'll have to inject the above JavaScript method in some how. Fortunately the WebBrowser control can also do for you by calling the eval() method:
WebBrowser.Document.InvokeScript("eval", javaScriptString);
For a more robust and complete implementation see the WebBrowser tools I wrote and the article explaining the ScriptingBridge which specifically aims to solve the problem you describe.
webBrowser.Document.InvokeScript("execScript", new object[] { "this.alert(123)", "JavaScript" })
for you supposed to be like this
webBrowser.Document.InvokeScript("execScript", new object[] { "obj.method()", "JavaScript" })

Categories

Resources