Connection response properties are camel case - javascript

I have no idea why this is happening. I'm connecting my angular 4 app to a signalR hub from the hosting server and it works like a charm (version 2.2.2)
I'm now having to add a second signalR connection to another project and for some unknown reason the properties of the response are all camelCase in stead of PascalCase. The jquery.signalr-2.2.2.js file however expects them to be PascalCase and throws an error that the server version is "undefined".
"Undefined" is logical since he's looking for res.ProtocolVersion and that property does not exist on my deserialized response. I do however have a res.protocolVersion and that one holds the exact value that he needs.
I've been losing a lot of time on this, any help is seriously appreciated!
Edit: #rory-mccrossan
I thought as much and that's why I commented out the server side json serializer/formatter code, but to no avail.
I'm taking any suggestion where to look next

So after Rory's hint I searched some more on the internet and of course, someone else has run into this problem:
SignalR : use camel case
However, the solution isn't working for me :/
Then I found a similar solution, here however you'll always have the default contract resolver except when the object comes from a certain library -the one with your view models-.
https://blogs.msdn.microsoft.com/stuartleeks/2012/09/10/automatic-camel-casing-of-properties-with-signalr-hubs/
Note: This is not the perfect solution, but it is one that worked best for my scenario
So I came up with a new solution all together that ties in nicely with the existing code that is giving me the problem.
The other way to go around this is to let your app use the DefaultContractResolver. SignalR will now connect, but the rest of your application will break. To mitigate this in the solution I'm working in I used two simple extension methods.
Firstly I extended the HttpConfiguration class to swap out the formatter for a CamelCasePropertyNamesContractResolver
public static class HttpConfigurationExtensions
{
public static HttpConfiguration ToCamelCaseHttpConfiguration(this HttpConfiguration configuration)
{
var jsonFormatter = configuration.Formatters.OfType<JsonMediaTypeFormatter>().FirstOrDefault();
bool needToAddFormatter = jsonFormatter == null;
if (needToAddFormatter)
{
jsonFormatter = new JsonMediaTypeFormatter();
}
jsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
jsonFormatter.SerializerSettings.DateTimeZoneHandling = DateTimeZoneHandling.Utc;
if (needToAddFormatter)
{
configuration.Formatters.Add(jsonFormatter);
}
return configuration;
}
}
The existing Web API will always return a HttpResponseMessage and that's why I could go about it in the way that I did.
Example of an api call
[Route("")]
[HttpPost]
public async Task<HttpResponseMessage> CreateSetting(Setting setting)
{
// the response object is basically the data you want to return
var responseData = await ...
return Request.CreateResponse(responseData.StatusCode, responseData);
}
I noticed every Api call was using the Request.CreateResponse(...) method. What I didn't see immediately is that Microsoft actually has foreseen all necessary overloads, this meant I couldn't just make my own Request.CreateResponse(...) implementation.
That's why it's called MakeResponse
public static class HttpRequestMessageExtensions
{
public static HttpResponseMessage MakeResponse<T>(this HttpRequestMessage request, T response) where T : Response
{
return request.CreateResponse(response.StatusCode, response,
request.GetConfiguration().ToCamelCaseHttpConfiguration());
}
}
The Response classes are the data structures that you want your api to return. In our api they all got wrapped into one of these structures. This results into an api with responses similar to the ones on the Slack API.
So now the controllers all use Request.MakeResponse(responseData)

Related

Blazor server side problem share javascript code

I'm developing my project with Blazor Server-side.
While I develop, I used javascript code to implement things that hard to implement by C#.
However, I'm facing something weird situation. (I guess it is problem for javascript)
Suppose there are 2 users(A, B). When 'A' user do some action that call javascript code, if 'B' user into same page, 'A' users action affects to 'B' user.
I implemented web page that have 3d scene with threejs. As I explained above, when User 'A' move some object with mouse event(mousemove, mousedown..), if User 'B' accesses the same page, 3d objects of B are moved to the location where User 'A' moved.
Originally, when user access to web page I developed, 3d objects's position should be 0,0,0.
My Guess
I don't use prototype or class(use variable and functions globally. I'm new to javascript.. )
Javascript runs on server-side(share resources??, If then, how can I solve it)
I'm guessing the javascript would be problem, but if you have any other opinions, would you please share?
Edited
I've solved this problem using DotNetObjectReference.Create(this);
C#
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
//send created instance to javascript
var dotNetObjRef = DotNetObjectReference.Create(this);
await JSRuntime.InvokeVoidAsync("SetObjectRef", dotNetObjRef);
}
await base.OnAfterRenderAsync(firstRender);
}
[JSInvokable]
public async Task enableSomething(bool bEnable)
{
var something = bEnable;
}
//== before edit
//[JSInvokable]
//public static async Task enableSomethingStatic(bool bEnable)
//{
// var something = bEnable;
//}
Javascript
var objectRef;
function SetObjectRef(ref) {
objectRef = ref;
}
//call c# function
objectRef.invokeMethodAsync("enableSomething", true);
It was problem of 'static' method as I guessed.
If you declare C# method called from javascript as 'static' and this method changes something of UI variable, this method can affect another users.
So I create instance of current page and send it javascript and when I need to call C# methods from javascript, I call methods using created instance.
Is there any problem or issue, please share it.
Sorry for my bad English.
JavaScript runs client side only. I don't see how two windows, let alone two users, would share data.
Almost for sure, the problem is that you are injecting a singleton service-- which means the server will use one instance for all users.
If so, you have two choices:
(1) add logic to your singleton service to incorporate users. (For example, a dictionary with UserID/Property name for key, and a column for Value)
(2) go to Startup.cs and change the suspect singleton service to .AddScoped(), which will create a new instance for each user.
For right now, I think the latter solution will solve your problem immediately. However, don't underestimate the value of Singletons-- they'll be very useful for other things.

Calling Java function from Rhino

Calling Javascript functions running inside Rhino from Java is easy enough - that after all is why Rhino was created. The thing I am having trouble establishing is this:
Context: I have a Phonegap CLI (v 6.3.3) Android project (API 19+) where I do a great deal of processing via loadable JavaScript running inside rhino
A Phonegap plugin - which I am creating at the same time as the actual Phonegap app - contains class called Storage which provides public, static, methods such as readFromFile(String fileName), writeToFile(String fileName,String data) etc.
What I want to be able to do is to call Storage.readFromFile etc from my loaded JavaScript code in Rhino.
Just how this should be done is not too clear to me. From the searches I have done thus far it involves using ScriptableObject.putProperty to pass the Java class in question, Storage in my case to JavaScript. However, how this should be done and then how it should be used at the JS end leaves me rather confused.
I would be most grateful to anyone here who might be able to point me in the right direction
Given that Rhino has less than 100 followers here it should perhaps come as little surprise that this question was not answered. In the mean time I have managed to find the solution myself and it turns out to be very simple. I share it below for the benefit of anyone else running into this thread.
My Storage class is very simple. It goes something like this
public class Storage
{
public static boolean haveFile(){}
public static boolean readFromFile(String fname){}
...
}
When I call Javascript from Java via Rhino I simply pass a new instance of the Storage class as the last of my function parameters
Context rhino = Context.enter();
Object[] functionParams = new Object[] {"Other parameters",new Storage()};
rhino.setOptimizationLevel(-1);
try
{
Scriptable scope = rhino.initStandardObjects();
String rhinoLog = "var log = Packages.io.vec.ScriptAPI.log;";
String code = /*Javascript code here* as shown separately below/;
rhino.evaluateString(scope, rhinoLog + code, "ScriptAPI", 1, null);
Function function = (Function) scope.get("jsFunction", scope);
Object jsResult = function.call(rhino,scope,scope,functionParams);
}
where the Javascript code is
function jsFunction(a,s)
{
//a - or a,b,c etc - here will be the "other" parameters
//s - will be the instance of the Java side Storage class passed above
//now you can do things like
s.writeToFile('fileName','fileData');
var fd = s.readFromFile('fileName');
s.dropFile('fileName');
...
}

OnContextCreated() in Cef not being called

I have a similar problem to the person in this post; I'm trying to extend the cefsimple.exe app included with the chromium embedded framework binaries to include a V8 handler. I implemented the OnContextCreated() method and made sure to extend RenderProcessHandler in the SimpleHandler class. I'm trying to implement a simple window bound variable called test_string; here's what my code looks like;
void SimpleHandler::OnContextCreated(
CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefV8Context> context)
{
CefRefPtr<CefV8Value> object = context->GetGlobal();
object->SetValue("test_string", CefV8Value::CreateString("this is a test"), V8_PROPERTY_ATTRIBUTE_NONE);
}
But the program never arrives at any breakpoints I add within the method, and the variable is undefined on any webpages I load within the app. I saw that one of the solutions in the other thread is to enable the settings.single_process flag, which i've done, but my code still doesn't reach the breakpoint.
To be clear, I'm accessing the variable on pages with window.test_string.
Make sure that you are sending that CefApp to CefExecuteProcess.
CefRefPtr<SimpleApp> app(new SimpleApp);
// CEF applications have multiple sub-processes (render, plugin, GPU, etc)
// that share the same executable. This function checks the command-line and,
// if this is a sub-process, executes the appropriate logic.
int exit_code = CefExecuteProcess(main_args, app, sandbox_info);
if (exit_code >= 0) {
// The sub-process has completed so return here.
return exit_code;
}
Found this solution here
Have you read through the General Usage guide? Some key points below
https://bitbucket.org/chromiumembedded/cef/wiki/GeneralUsage#markdown-header-cefapp
https://bitbucket.org/chromiumembedded/cef/wiki/GeneralUsage#markdown-header-processes
The single_process mode is not supported so I've never used it. In general I'd avoid it. The multi process architecture means you need to attach the debugger to the process. The Chromium guide is relevant to CEF in this instance.
https://www.chromium.org/developers/how-tos/debugging-on-windows#TOC-Attaching-to-the-renderer
you need to ensure your App is derived from CefRenderProcessHandler
not SimpleHandler!!!
class SimpleApp : public CefApp
, public CefRenderProcessHandler
{
virtual void OnContextCreated(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefV8Context> context) OVERRIDE;
valdemar-rudolfovich says you need to pass instance of SimpleApp in
CefExecuteProcess

Writing JS code to mimic api design

We're planning on rebuilding our service at my workplace, creating a RESTful API and such and I happened to stumble on an interesting question: can I make my JS code in a way that it mimics my API design?
Here's an example to illustrate what I mean:
We have dogs, and you can access those dogs doing a GET /dogs, and get info on a specific one by GET /dogs/{id}.
My Javascript code would then be something like
var api = {
dogs : function(dogId) {
if ( dogId === undefined ) {
//request /dogs from server
} else {
//request /dogs/dogId from server
}
}
}
All if fine and dandy with that code, I just have to call api.dogs() or api.dogs(123) and I'll get the info I want.
Now, let's say those dogs have a list of diseases (or whatever, really) which you can fetch via GET /dogs/{id}/disases. Is there a way to modify my Javascript so that the previous calls will remain the same - api.dogs() returns all dogs and api.dogs(123) returns dog 123's info - while allowing me to do something like api.dogs(123).diseases() to list dog 123's diseases?
The simplest way I thought of doing it is by having my methods actually build queries instead of retrieving the data and a get or run method to actually run those queries and fetch the data.
The only way I can think of building something like this is if I could somehow, when executing a function, if some other function is chained to the object, but I don't know if that's possible.
What are your thoughts on this?
I cannot give you a concrete implementation, but a few hints how you could accomplish what you want. It would be interesting to know, what kind of Server and framework you are using.
Generate (Write yourself or autogenerate from code) a WADL describing your Service and then try do generate the Code for example with XSLT
In my REST projects I use swagger, that analyzes some common Java REST Implementation and generates JSON descriptions, that you could use as a base for Your JavaScript API
It can be easy for simple REST Apis but gets complicated as the API divides into complex hierarchies or has a tree structure. Then everything will depend on an exact documentation of your service.
Assuming that your JS application knows of the services provided by your REST API i.e send a JSON or XML file describing the services, you could do the following:
var API = (function(){
// private members, here you hide the API's functionality from the outside.
var sendRequest = function (url){ return {} }; // send GET request
return {
// public members, here you place methods that will be exposed to the public.
var getDog = function (id, criteria) {
// check that criteria isn't an invalid request. Remember the JSON file?
// Generate url
response = sendRequest(url);
return response;
};
};
}());
var diseases = API.getDog("123", "diseases");
var breed = API.getDog("123", "breed");
The code above isn't 100% correct since you still have to deal with AJAX call but it is more or less what you what.
I hope this helps!

Simplest approach to Node.js request serialisation

I've got the classic asynchronous/concurrency problem that folks writing a service in Node.js at some point stumble into. I have an object that fetches some data from an RDBM in response to a request, and emits a fin event (using an EventEmitter) when the row fetching is complete.
As you might expect, when the caller of the service makes several near-simultaneous calls to it, the rows are returned in an unpredictable order. The fin event is fired for rows that do not correspond to the calling function's understanding of the request that produced them.
Here's what I've got going on (simplified for relevance):
var mdl = require('model.js');
dispatchGet: function(req, res, sec, params) {
var guid = umc.genGUID(36);
mdl.init(this.modelMap[sec], guid);
// mdl.load() creates returns a 'new events.EventEmitter()'
mdl.load(...).once('fin',
function() {
res.write(...);
res.end();
});
}
A simple test shows that the mdl.guid often does not correspond to the guid.
I would have thought that creating a new events.EventEmitter() inside the mdl.load() function would fix this problem by creating a discrete EventEmitter for every request, but evidently that is not the case; I suppose the same rules of object persistence apply to it as to any other object, irrespective of new.
I'm a C programmer by background: I can certainly come up with my own scheme for associating these replies with their requests, using some circular queue or hashing scheme. However, I am guessing this problem has already been solved many times over. My research has revealed many opinions on how to best handle this--various kinds of queuing implementations, Futures, etc.
What I'm wondering is, what's the simplest possible approach to good asynchronous flow control here? I don't want to get knee-deep in some dependency's massive paradigm shift if I don't have to. Is there a relatively simple, canonical, definitive solution, and/or widespread consensus on which third-party module is best?
Could it be that your model.js looks something like this?
module.exports = {
init : function(model, guid) {
this.guid = guid;
...
}
};
You have to be aware that the object you're passing to module.exports there is a shared object, in the sense that every other module that runs require("model.js") it will receive a reference to the same object.
So every time you run mdl.init(), the guid property of that object is changed, which would explain your comment that "...a simple test shows that the mdl.guid often does not correspond to the guid".
It really depends on your exact implementation, but I think you'd want to use a class instead:
// model.js
var Mdl = function(model, guid) {
this.guid = guid;
};
Mdl.prototype.load = function() {
// instantiate and return a new EventEmitter.
};
module.exports = Mdl;
// app.js
var Mdl = require('model.js');
...
var mdl = new Mdl(this.modelMap[sec], guid);
mdl.load(...)

Categories