Creating JavaScript in C # and Subsequent Testing

We are currently developing an ASP.NET MVC application that actively uses attribute-based metadata to generate JavaScript generation.

The following is an example of the type of methods we write:

function string GetJavascript<T>(string javascriptPresentationFunctionName, string inputId, T model) { return @"function updateFormInputs(value){ $('#" + inputId + @"_SelectedItemState').val(value); $('#" + inputId + @"_Presentation').val(value); } function clearInputs(){ " + helper.ClearHiddenInputs<T>(model) + @" updateFormInputs(''); } function handleJson(json){ clearInputs(); " + helper.UpdateHiddenInputsWithJson<T>("json", model) + @" updateFormInputs(" + javascriptPresentationFunctionName + @"()); " + model.GetCallBackFunctionForJavascript("json") + @" }"; } 

This method generates some cauldron and hands to various other methods that return strings. Then the whole batch is returned as a string and written to the output.

I have some questions):

1) Is there a better way to do this other than using large string blocks?

We've looked at using StringBuilder or Stream Response, but that seems pretty noisy. Using string.format is starting to get complicated.

2) How are you going to test this code? It seems a bit amateur, just doing string comparisons looking for specific output in a string.

3) How about actually testing the final JavaScript result?

Thanks for your input!

+4
source share
4 answers

Usually I try to create a separate .js file for most / all of my javascript codes. Usually, I need the generic bahvior to be applied to many elements that are dynamically created using ASP controls or server-side code, so I cannot encode everything into a .js file.

I found that the main reason you want to generate javascript on the server is because you will not know the identifiers of the elements until the page is displayed. Therefore, I am trying to condense this dependency as much as possible so that I generate as little javascript as possible. For example, in traditional ASP.Net (not MVC), if I were to represent a set of forms, for example, in each example with several fields, then I would probably have something in this code:

 protected void FormRepeater_ItemDataBound(object sender, RepeaterItemEventArgs e) { Control form = e.Item.FindControl("MyForm"); ClientScript.RegisterStartupScript(this.GetType(), "prepareForm_" + form.ClientID, @"prepareForm('" + form.ClientID + "');", true); } 

A separate .js file will include a definition of the prepareForm function, which will be something like this:

 // define a formPresenter "class" that encapsulates the behavior for a given form function formPresenter(formId) { this.setFirstName = function(value) { $("#" + formId + "_FirstName").val(value); } this.setLastName = function(value) { $("#" + formId + "_LastName").val(value); } // create other functions to handle more complicated logic // clear fields this.clearInputs = function() { this.setFirstName(""); this.setLastName(""); //... } // receive Json object this.handleJson = function(json) { this.clearInputs(); // populate fields with json object this.setFirstName(json.FirstName); this.setLastName(json.LastName); //... } // "constructor" logic } function prepareForm(formId) { // create a new formPresenter object and shove it onto the specified element as the "presenter" document.getElementById(formId).presenter = new formPresenter(formId); } 

Now almost all of your actual logic is in its own .js file, which should be much easier to maintain. If you need to access the formPresenter object for this form, you just need to get a link to any element referenced by the formId parameter and access the host variable:

 "document.getElementById(" + form.ClientID + ").presenter.handleJson(json);" 

Note. Since I use jQuery, I found it less necessary to even include any javascript generated by the server. Usually I can find the elements I need by looking for a specific CSS class name (or something like that) and do whatever installation / initialization I need.

+1
source

In our project, we do a lot of JS generation, and for this we use StringBuilder.

 StringBuilder sb = new StringBuilder(); sb.Append("some javascript stuff") .Append("some more") .AppendFormat("formatted stuff {0}", "here"); return sb.ToString(); 

This is not very, but there will be no solution.

And with regard to testing, we actually do not conduct any unit tests of the generated code. Before release, people go and check all the features to make sure they work as expected.

+1
source

If you don't care about super-duper performance, you can use the template language to create javascript.

Then for unit testing, you simply populate the templates with the appropriate bindings / variables, and then run it through a Javascript evaluator like Rhino, or something equivalent to .NET, to at least check the syntax, if not the actual JS code.

Other than that, I would seriously question the design of the software that Javascript generates like this. It also looks like you are using jQuery, but referring to $ directly, which may lead to some problems in the line.

If the compilers generating Javascript are one thing (ala GWT), but I would separate your client-side JS code as much as possible from your .NET code (not to mention that your .NET code is like server-side JS -conflict discussion).

This is a fashionable design for separating a clip from a server called SOFEA. I let you google.

+1
source

We created a library specifically for embedding JavaScript in a free-like syntax in our C # code, and then made it open source.

Take a look at Adam.JSGenerator .

+1
source

Source: https://habr.com/ru/post/1306780/


All Articles