I'm trying out Jint and want to implement the fetch api to use from js. The second argument is a nested js object that is passed in:
fetch('https://example.com', {
method: 'post',
headers : {
authorization : 'xyz'
}
});
What is the signature for the C# function to pass in? I tried
private static string Fetch(string uri, object init)
First and saw Jint passed in an ExpandoObject, I made this:
private static string Fetch(string uri, ExpandoObject init)
But Jint use the JsValue and ObjectInstance object internally right? These also have better sematics to work out is what you got passed in was an object or array etc, but this throws an error:
private static string Fetch(string uri, ObjectInstance init)
: 'No valid constructors found'
What would be the recommended way to pass these objects to C#? I want to have as little friction between the js and C# side of the app as I'll be making quite a few calls back and forth (which is why I'm looking at Jint coming from ClearScript)
Some choices:
JsValue
The object is passed as is.
You can't use any other derived type because jint only checks JsValue. To use ObjectInstance, cast it on C# side.
dynamic
This is the equivalent of ExpandoObject.
Jint will convert an ObjectInstance to an ExpandoObject first if the parameter type is other than JsValue.
IDictionary<string,object> or any other generic interface that ExpandoObject implemented
Same as dynamic.
A custom type that the input object is able to convert to.
You could define the object as class or struct, and define the entries as field or property. The name of the member can be capitalized. Notice that this way uses reflection, so it's not effcient.
For instance, you can define it like this:
struct Header
{
public string authorization;
}
class Init
{
public string Method { get; set; }
public Header Headers { get; set; }
}
object
Always works.
Related
I have a method that works with a defined data object type, like this:
public static ItemEdificio JSONtoOBJECT(this string JSONstring)
{
return new JavaScriptSerializer().Deserialize<ItemEdificio>(JSONstring);
}
Is there any way to convert the "ItemEdificio" into something than actualy vary according to the object type?
Keep in mind that this is made using the Newtonsoft library.
public static T JSONtoOBJECT<T>(this string JSONstring)
{
return new JavaScriptSerializer().Deserialize<T>(JSONstring);
}
Thats what generics (https://msdn.microsoft.com/en-us/library/0x6a29h6.aspx) are for.
You call it like this: MyType instance = jsonData.JSONtoOBJECT<MyType>();
I have got one method in class
public JObject InvokeMethod(string a_sMethod, params object[] a_params)
And I need to call this method in bool Test() in another class
protected override bool Test ()
{
logger.Write("Test1");
WebServer ws = new WebServer();
ws.InvokeMethod();
}
I need to call these two params: a_sMethod and a_params in other class.
Have anyone some idea how to do that ?
public string a_sMethod{get; set;}
does not work in this case. I get an error: There is no argument that correspondsto the required formal parameter 'a_sMethod' .
I get an error: There is no argument that correspondsto the required
formal parameter 'a_sMethod' .
error occurs here because you haven't specified the correct arguments for the method.
ws.InvokeMethod();
The method signature below expects a string and any number of data to be passed in:
public JObject InvokeMethod(string a_sMethod, params object[] a_params)
Example:
ws.InvokeMethod("testing", 1,2,3,4,5,5); // this is just for illustration, you can pass in the data you want to work with.
There are disadvantages of using object type as params array but it's beyond the scope of this question, so I will let that pass.
UPDATE
if you want to use properties, that's also simple.All you have to do is just set the data for that particular property and pass them in as the InvokeMethod(string a_sMethod, params object[] a_params) method parameters expect.
What I want is to have a method that accepts a type as a parameter and cast a variable into that type within the method in C#
as an example I want to pass a UI element to this helper method and extract its DataContext's (which is bound dynamically at runtime) Description. I want to use this method in a more generalized manner so that I can pass in the DataContext's type also.
private String GetDescription(FrameworkElement element, Type type) {
return (element.DataContext as type).Description;
//or
//return ((type)element.DataContext).Description;
}
both the ways it ends up with a compile time error.
I tried using generics as well but it was not successful as i might not understood properly.
It would be really great if someone could explain how to do this in a simple manner.
Write a interface and implement it for your classes:
public interface IDescribable
{
string Description{get;}
}
Implement this object on your desired classes:
public class MyClass:IDescribable
{
// other members
public string Description{get; set;}
}
Then you could even write an extension method to extract the string:
public static string GetDescription(this FrameworkElement element)
{
var contextData= element.DataContext as IDescribable;
return contextData!=null
? contextData.Description
:"";
}
Or if you don't want implement interface use reflection:
private string GetDescription(FrameworkElement element)
{
var decProp= element.DataContext.GetType().GetProperty("Description");
return decProp!=null
?decProp.GetValue(element.DataContext)
:"";
}
Why is it that when I use dynamic with json.net I get a runtime binding exception then calling a method without casting but I can do assignments not problem
private static void Main()
{
dynamic json = JObject.Parse("{\"Test\":23}");
var t = json.Test;
int a = t; //Success
Prop = t; //Success
Func(t); //RuntimeBinderException
}
private static void Func(int i){}
private static int Prop { get; set; }
When I cast it to the correct type there are no errors but I would prefer to not have to do that. Am I doing something wrong, is this a problem in the json.net library or is a language restriction.
Edit:
This is to solve a problem where I don't have control over the methods signature and I don't want to cast it on every call.
This is because json.Test returns a JValue and JValue has a dynamic TryConvert. So if you do an implicit static conversion by pointing it to an int or cast to an int it will at runtime call that TryConvert and you have success. However if you use that dynamically typed variable in a method argument, the c# runtime looks for a method named Func with an argument that best matches 'JValue' it will not try to call 'TryConvert' for every permutation of a possible method (even if it's only one) thus you get the runtime binding error.
So the simplest solution is to just cast on every call or set a statically typed variable each time you want to pass a JValue as an argument.
There is actually a more general question and answer of this same issue too if you are looking for more info:
Pass a dynamic variable in a static parameter of a method in C# 4
private static void Func(dynamic i){}
will solve the issue.
Here is what I'm trying to setup
My class is named Inventory
I have a static function named List_Departments()
I would like to be able to add an additional function to modify the previous
For Example: Inventory.List_Departments().ToHTML() would return an HTML formatted string containing the data from List_Departments()
If possible i'd like to reuse the same code for another function such as List_Categories()
I would really appreciate a nudge in the right direction on this. I just can't seem to find the correct terminology/ search term to pull up the info I need. Thank you very much for your help, and sorry for the somewhat stupid question.
You need to make the List_Departments method return an object that has a ToHtml method.
Depending on what your exactly methods are returning, you might make a class called something like ObjectList, which would have a ToHtml method, and have the ListDepartments and ListCategories return instances of it.
Alternatively, and especially if your methods are returning existing classes such a DataTable, you could make an extension method for that class called ToHtml.
It sounds like what you're referring to is Extension Methods
Basically, your functions List_Departments() and List_Categories are returning some typed object correct? That being, the object returned would have to have a Method created in it's class definition called ToHTML(). If the two functions return the same type of object then, you only need to define it once. If they return two different types, then you will have to define the ToHTML() method on both return types class definitions.
Unless I'm missing something here, these two functions don't require the static modifier.
If the returning types are types that you don't have source code access to, then you can define an extention method for each type that will process the type of object being returned and can display the ToHTML() for it.
You didn't supply much info, but using Extension methods seems a good approach to me.
An example turning an string into an int:
public static class StringMethods {
public static int ToInt(this String subject) {
int result;
int.TryParse(subject, result);
return result;
}
}
Assuming List_Departments returns Department:
public static class DepartmentMethods {
public static string ToHtml(this Department subject) {
// Whatever you want to do.
}
}
If you do have acces to the internals of the type returned by List_Departments, you can also just add ToHtml there.
the search term you're looking for is Method Chaining :-)
http://www.bing.com/search?q=method+chaining
This is something along the lines of what jQuery does. Basically, you make an object that has all of the methods that you want to be able to chain. Then, using the builder pattern, you can chain all the calls together until you call some final "result" method (ToHtml in your case).
public class Inventory
{
private IEnumerable<Departments> departments;
private IEnumerable<Items> items;
public Inventory ListDepartments()
{
// load up departments to a class level field
return this;
}
public Inventory ListItems()
{
// load up items to a class level field
return this;
}
public string ToHtml()
{
// convert whichever enumerable was previously loaded to HTML
return stringBuilder.ToString();
}
}
That lets you do things such as:
inventory.ListDepartments().ToHtml();
The ToHTML() function is a function that acts on the type returned from List_Departments()
For example:
if Inventory.GetProduct(0) returns an int. You can use Inventory.GetProduct(0).ToString() because ToString() is a method of an integer type.
In order to do this, List_Departments() would have to return a custom object that has a method called ToHTML() say
public class Department() {
public HtmlDocument ToHTML() {
//Create the html document to return here
}
}