C# - Read JavaScript file and access variable - c#

I have a JavaScript file with variables defined and values assigned to them. Is it possible to read the .js file with C# and easily retrieve the variables and values? I know what the variable names will be, but the values will be a json string. I'm hoping I don't have to resort to regular expressions.
EDIT: I do not have control over the contents of the JavaScript file. A third party drops the file to a location and I need to pick it up, read it, and parse it.
EDIT 2: Ok, forget I mentioned json. That actually has nothing to do with my question...which at this point doesn't seem to have a simple solution. So I went with reading the .js file line by line, searching for the variable name, and getting the value. Code below for reference.
using (StreamReader r = new StreamReader("myFile.js"))
{
while(r.Peek() >= 0)
{
var line = r.ReadLine();
if(line.IndexOf("myVariableName") > -1)
{
var arr = line.split("=");
var variable = arr[0].Trim();
var value = arr[1].Trim();
}
}
}

I had a similar issue in a Browser Helper Object I needed to to create to extract data from a web generated report and store it in a local file system.
I did following to access js values:
mshtml.IHTMLDocument document = (mshtml.IHTMLDocument)this.Explorer.IWebBrowser_Document;
object script = document.Script;
if (script != null)
{
// Make the call:
var jsvar = script.GetType().InvokeMember("eval", BindingFlags.InvokeMethod, null, script, new object[] { "HIS_VisitNumber" });
// Cast...
_strHISVisit = (string)jsvar;
// Release the script object, and possibly the document object.
Marshal.ReleaseComObject(script);
}
Here this.Explorer is the explorer object that is available through the Band Object (the BHO).
But of course, this approach is only possible if you would be able to leverage a browser (IE) which has all the facilities to load and execute js.
If you could not do such a thing, I guess what you would need is a full C# js parser or am I not understanding your question correctly?
In the latter case, you could use Javascript .NET

If you are a web developer and want to send data from a JavaScript file (client side) to a C# file (server side), you can use jQuery Ajax. You can pass variables to a function in a C# file. Remember that you must add the [WebMethod] attribute to your C# function, and the function must be static.
$.ajax({
type: "post",
url: "Default.aspx/YourMethodName",
contentType: "application/json; charset=utf-8",
dataType: "json",
data: JSON.stringify({ varOne: one , varTwo:two }),
success: function (v) {
alert("Success");
},
error: function (error) {
alert("Error");
},
complete: function () {
alert("Complete");
}
});

Related

Using a C# function in a .jsx File

I am trying to Download a File from my mvc (C# Application, from my local Database).
I also have a .jsx File in which a "Button" is pressed and a certain function from javascript gets executed.
I want to implement another function (in my C# Code) that gets also gets executed when the "Button" gets clicked.
My Function is of the Type "FileStreamResult" so I should get a FileStream which later should be put in a Xml-type File.
The Question is now how do i access the C# Method in my .jsx File?
public FileStreamResult Download(Guid id)
{
//Download of the File happens here
}
the Code above should be executed in this:
// Send Button Click
handleSendButtonClick(event) {
const url = "/Test/Test/...";
const options = {
method: "POST",
headers: {
Accept: "application/json",
"Content-Type": "application/json;charset=UTF-8",
},
};
fetch(url, options)
.then((response) => response.json())
.then((ebinContent) => {
let ebinUint8Array = new Uint8Array(ebinContent.data.length);
for (let i = 0; i < ebinUint8Array.length; i++) {
ebinUint8Array[i] = ebinContent.data[i];
}
handleSendMessages(event, ebinUint8Array);
});
};
I barely know .jsx but im familiar in C#.
Im trying to put the C# function into the .jsx file but I just dont know how to get it done.

Uploading Images with ASP.NET MVC

I'm building a craigslist clone with ASP.NET MVC + SQL Server and I'm stuck. I'm not sure how to go about uploading and storing images. Through my research it seems better to store images in the server's file system rather than on the SQL database, but it can be stored in SQL as varbinary(MAX). Is my assessment correct?
I have a dropzone where you can click and drag multiple images into it and javascript that converts them to an array of blobs. So far I have the submit button make an ajax post request with the array of blobs that I can see in the Controller through Request.Form.Files. However I also want to send over other data from the rest of the form using the ViewModel.
This is the javascript that creates the blob array and posts it with ajax:
function buildFormData() {
//Create and build formData
formData = new FormData();
images.forEach((image, index) => {
formData.append('images[]', image, 'image:' + index);
})
//Make post request
$.ajax({
url: 'Home/UploadImage',
type: 'POST',
data: formData,
processData: false,
contentType: false,
});
}
function setupReader(file) {
//console.log("File is blob? ", file instanceof Blob); -> true
images.push(file);
var name = file.name;
var reader = new FileReader();
reader.onload = function (e) {
// Create HTML element for image (simplified)
var previewImg = '<img class="preview-image" src="' + e.target.result + '" />';
//Add img preview element to boxZone
boxZone.append(previewImg);
}
reader.readAsDataURL(file);
}
function readFiles(input) {
console.log($);
for (var i = 0; i < input.files.length; i++) {
setupReader(input.files[i]);
}
console.log("Images: ", images);
}
This seems like a good start, I can see the files in Request.Form.Files using the debugger inside of Home Controller UploadImage method, but I bet there's an easier way using the ViewModel.
What's the best way to include a variable-length array of blobs in my View model? Maybe using the FormFile or FormFileCollection classes? Or should I just use ajax to post the rest of the form data along with the images like above? Any solution I haven't considered?
Secondly, once the images are on the server I'm not sure how exactly to use the file system to store them. This is a snippet of code from the .NET docs that seems to be what I'm looking for:
using (System.IO.FileStream fs = System.IO.File.Create(pathString))
{
for (byte i = 0; i < 100; i++)
{
fs.WriteByte(i);
}
}
These are the questions I'm basically asking:
Should I store Images on the file system or SQL database?
2.Should I use Ajax to make the request?
If not:
How should I use a ViewModel to send an array of blobs?
Should I use FormFile or FormFileCollection classes to represent the images in the view model? Or a custom Image class with a byte[] field to hold the image itself?
Can anyone let me know if I'm going in the right direction, and which methods I should use to upload and store these images that I haven't considered?

httpwebrequest posting json incorrectly

Edit: Ok, so it looks like posting as application/json needs to be handled server side separate than a form. Is there any better way to post a form in C# as a complicated object? String:String just doesn't cut it. For example, I want to be able to use Dictionary to produce:
{
"data_map":{"some_value":1,"somevalue":"2"},
"also_array_stuffs":["oh look","people might", "want to", "use arrays"],
"integers_too":4
}
---OP---
I've looked on SO and other places. I'm just trying to POST a JSON string to a URL, but the server side keeps interpreting the content as a string instead of a query dict. We have other clients that aren't in c# that hit the server side fine (in HTML, JS, Objective-C, Java), but for some reason the POST data comes back wonky from the C# client.
C# source:
private static Dictionary<string,object> PostRequest(string url, Dictionary<string, object> vals)
{
var httpWebRequest = (HttpWebRequest)WebRequest.Create(BaseURL+url);
httpWebRequest.ContentType = "application/json; charset=utf-8";
httpWebRequest.Method = "POST";
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
string json = JsonFx.Json.JsonWriter.Serialize(vals);
//json = json.Substring(1,json.Length-1);
streamWriter.Write(json);
streamWriter.Close();
}
try
{
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
string response = streamReader.ReadToEnd();
Dictionary<string,object> retval = JsonFx.Json.JsonReader.Deserialize<Dictionary<string,object>>(response);
return retval;
}
}
catch(WebException e)
{
}
return null;
}
This gets called like:
public static void Main (string[] args)
{
Dictionary<string,object> test = new Dictionary<string, object>();
test.Add("testing",3);
test.Add("testing2","4");
Dictionary<string,object> test2 = PostRequest("unitytest/",test);
Console.WriteLine (test2["testing"]);
}
For whatever reason, this is the request object that gets passed though:
<WSGIRequest
GET:<QueryDict: {}>,
POST:<QueryDict: {u'{"testing":3,"testing2":"4"}': [u'']}>,
COOKIES:{},
META:{'CELERY_LOADER': 'djcelery.loaders.DjangoLoader',
'CONTENT_LENGTH': '28',
'CONTENT_TYPE': 'application/json; charset=utf-8',
'DJANGO_SETTINGS_MODULE': 'settings.local',
'GATEWAY_INTERFACE': 'CGI/1.1',
'HISTTIMEFORMAT': '%F %T ',
'HTTP_CONNECTION': 'close',
'LANG': 'en_US.UTF-8',
'QUERY_STRING': '',
'REMOTE_ADDR': '127.0.0.1',
'REMOTE_HOST': '',
'REQUEST_METHOD': 'POST',
'RUN_MAIN': 'true',
'SCRIPT_NAME': u'',
'SERVER_PORT': '9090',
'SERVER_PROTOCOL': 'HTTP/1.0',
'SERVER_SOFTWARE': 'WSGIServer/0.1 Python/2.7.2+',
'SHELL': '/bin/sh',
'SHLVL': '1',
'SSH_TTY': '/dev/pts/0',
'TERM': 'xterm',
'TZ': 'UTC',
'wsgi.errors': <open file '<stderr>', mode 'w' at 0x7f3c30158270>,
'wsgi.file_wrapper': <class 'django.core.servers.basehttp.FileWrapper'>,
'wsgi.input': <socket._fileobject object at 0x405b4d0>,
'wsgi.multiprocess': False,
'wsgi.multithread': True,
'wsgi.run_once': False,
'wsgi.url_scheme': 'http',
'wsgi.version': (1, 0)}>
[18/Oct/2012 19:30:07] "POST /api/1.0/unitytest/ HTTP/1.0" 200 31
Some of the more sensitive data in the request has been removed, but is irrelevant
Ugh, I hope I don't make a habit of answering my own questions.
So, Posting Json this way is different than a normal form submission. That means if your server side is expecting just a normal form submission it will not work. The C# code does as it's intended to do, but only submits a JSON string as the POST body. While this may be convenient for people who validate, clean, and handle raw input anyway, keep in mind that if you're using a normal web framework, you will have to write an alternate condition to accept the raw string.
If anybody has an idea how to do a form submission in C# containing objects more complex than a hashmap/dictionary of strings, then I will upvote your answer and give you lots of hugs. For now, this hacky nonsense will have to do.
Well, once, a long time ago I implemented a banking app front end, which, made massive use of JSON for communication between client and server.
It was a clean way to find complex object to and from the server, no need to make complex cleanup or raw string processing.
The key was using WebServices designed for ajax on the server side, your web server class should look like this:
[WebService(Namespace = "http://something.cool.com/")]
[ScriptService] // This is part of the magic
public class UserManagerService : WebService
{
[WebMethod]
[ScriptMethod] // This is too a part of the magic
public MyComplexObject MyMethod(MyComplexInput myParameter)
{
// Here you make your process, read, write, update the database, sms your boss, send a nuke, or whatever...
// Return something to your awaiting client
return new MyComplexObject();
}
}
Now, on your client-side, set things up to make ASP.NET talk to you in JSON, I'm using JQuery for making the ajax requests.
$.ajax({
type: 'POST',
url: "UserManagerService.asmx/MyMethod",
data: {
myParameter:{
prop1: 90,
prop2: "Hallo",
prop3: [1,2,3,4,5],
prop4: {
// Use the complexity you need.
}
}
},
contentType: 'application/json; charset=utf-8',
dataType: 'json',
success: function(response) {
alert(response.d);
}
});
Anything that ASP want to return as the result for your ScriptMethod, is going to be contained in the response.d variable. So, let's say you are returning from the server a complex object, "response.d" is the reference to your object, you access all the object members using the dot notation as usual.

jQuery ajax POST call to ASP.NET Web Service randomly fails

I'm developing a web site for mobile devices that makes ajax calls using jQuery (v 1.7.2) to an ASP.NET (v 2.0.50727) Web Service.
The call works correctly about 95% of the time, but it will randomly fail, returning a 500 internal server error. It fails on the server side before the first line of code is ever executed (the first line writes to the event log).
I haven't seen the call fail using a desktop browser that I remember, but I've seen it fail enough using an iPad. I added
<browserCaps userAgentCacheKeyLength="256">
to the Web Service's web.config file, but that hasn't helped.
javascript:
$.ajax({
type: "POST",
url: serverURL + "/getImage",
data: '{"formURL":"' + url + '", "rowNumber":"'+rowNumber+'"}',
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (msg,textStatus, jqXHR) {
...
}, error: function(xhr, ajaxOptions, thrownError) {
...
}
}).done(function(){
console.log("getImage call is done");
});
Example data passed to the web service:
'{"formURL":"fileName.xml", "rowNumber":"1"}'
c#
[WebMethod(EnableSession = true)]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public string getImage(string formURL, string rowNumber) {
log("Retrieving image of form " + formURL);
string image = "";
string username = /*retrieve username*/;
string password = /*retrieve password*/;
if (username != null && username != "") {
image = /*code to retrieve the image*/;
}
return image;
}
private void log(string message) {
EvLog.WriteToEventLog(DateTime.Now.ToString("MM:dd:yyyy H:mm:ss:fff") + Environment.NewLine + message, 10);
}
The only thing I've found that has slightly helped me, is when the call fails because the response headers from the Web Service contain "jsonerror: true" though I haven't been able to pinpoint why it would randomly fail.
Any help is appreciated!
Assuming it truly is a JSON error, my first thought is that the data being passed into the parameters is incorrect.
The following line is quoting the contents of variables, which I assume is being loaded from somewhere else in the code:
data: '{"formURL":"' + url + '", "rowNumber":"'+rowNumber+'"}',
Assuming you are already making sure rowNumber is an integer value and wouldn't break it, the likelihood is that the 'url' variable is breaking your JSON format. The easiest way this could happen is if you had an unescaped quote in the filename, especially if it's closing your parameter values earlier than expected when it gets concatenated.
There's always the possibility of the characters not being valid for the charset. Do you have an example data that triggers the failure? The example provided looks nice and clean, so I'm assuming it wasn't one of the error cases.
Don't build your data in this way
data: '{"formURL":"' + url + '", "rowNumber":"'+rowNumber+'"}',
It can cause malformed JSON string.
Instead of this stringify your JavaScript object using JSON.stringify method:
data: JSON.stringify({formUrl: url, rowNumber: rowNumber}),
JSON.stringify will make all job for you to represent your object as valid JSON string.

Calling a web service from Javascript (passing parameters and returning dataset)

I have created a web service in C# and now need to call it from a mobile app. I'm trying to create a Windows 7 mobile app, but using HTML5 and Javascript not the native code. The web service takes 2 parameters, Email and Password, and returns a Dataset. I don't really have any javascript experience (or web services experience for that matter, trying to learn with this project), and when trying to research how to call a web service using javascript I just found too much information and didn't know where to begin because so many other technologies were also mentioned.
So I decided to try things out and this is what I came up with so far:
<script type="text/javascript">
document.addEventListener("deviceready", onDeviceReady, false);
// once the device ready event fires, you can safely do your thing! -jm
function onDeviceReady() {
}
function LoginButton_onclick() {
UpdateChildrenApp.PhoneWebServices.GetMyChildren(document.getElementById('EmailBox').value,document.getElementById('PasswordBox').value, OnComplete, OnError)
}
function OnComplete(result) {
for (var i = 0; i < result.tables[0].rows.length; i++)
document.getElementById('Test').innerHTML += ''+(result.tables[0].rows[i].col_name);
}
function OnError(result) {
document.getElementById('Test').innerHTML ='Error :'+result.get_message();
}
</script>
This code does nothing when I press the submit button. Could someone please point out what the problems are and how I can fix them or suggest what I should research to address the problems and put me on the right track? Any help is greatly appreciated.
First, your webservices should return a JSON object if you want to use it in javascript.
You can of course return any XML/string, but using JSON will be A LOT easy to use the data in javascript.
Then, I would advise you to use jquery to call the webservice, as jquery will do a lot of work for you.
Read this article, it should help you set different components correctly:
I would use jQuery to do this kind of thing.
The ajax functionality its provides is really easy to use.
I would use the Revealing Module Pattern (RMP) and 2 javascript files. If you're unfamiliar with the RMP, there is a great post covering it here:
http://weblogs.asp.net/dwahlin/archive/2011/08/02/techniques-strategies-and-patterns-for-structuring-javascript-code-revealing-module-pattern.aspx
I find that if I dont employ some kind of structure to my js code using the RMP, I just end up with a mess of functions in one file.
Id have Startup.js and Dataservice.js and they would look something like this:
Startup.js
var Startup = function () {
var isValid,
dataObject = {},
populateDataObject = function () {
dataObject.dealer = $("[id$='_txtUser']").val();
dataObject.password = $("[id$='_txtPassword']").val();
},
init = function () {
var dealerId = 0;
$("[id$='_SubmitButton']").bind('click', function (evt) {
evt.preventDefault();
populateDataObject();
if (isValid) {
Dataservice.processLoginRequest(dataObject, processLoginRequestResult);
}
});
};
return {
init: init,
processLoginRequestResult: processLoginRequestResult
};
} ();
Dataservice.js (assumes old school .asmx, change as needed)
var Dataservice = function () {
$.ajaxSetup({
type: "POST",
contentType: "application/json; charset=utf-8",
dataType: "json"
});
var serviceBase = '../services/LoginService.asmx/',
processScreenRequest = function (valObject, callback) {
$.ajax({
url: serviceBase + "ProcessLoginRequest",
data: JSON.stringify(valObject),
success: function (json) {
callback(json);
}
});
};
return {
processScreenRequest: processScreenRequest
};
} ();
and then I would include refereces to these 2 js files as well as jquery in my html page.
I hope this helps.
I've used Dojo for this once, its pretty simple you can make xhrget or xhrpost requests. It has a function called load that is the callback where you can modify the contents of the HTML components in the page.
Use these links : http://dojotoolkit.org/reference-guide/1.7/dojo/xhrGet.html

Categories

Resources