reference javascript content coming from db instead of static file - javascript

I am developping an asp.net web application :
In the website folder, I have a folder called "integrations" containing a list of js files (name1.js, name2.js, name3.js ...)
A user makes a http request to a mvc controller method where he gives as input a "name".
This method gives the "name" as a property of a viewmodel to a razor view containing the following code :
This razor view is returned to the user.
The previous code is working well, but I would like to add an improvment. Actually you need to add a js file inside the folder integrations,
and you cannot do that when the application is running in production.
So I would like instead of having a script tag referencing a file placed inside the integrations folder to have a script tag containing a js content
coming from a data table like this :
name : jscontent
name1 : jscontent1
name2 : jscontent2
But I don't know how to changed this :
<script src="~/integrations/#(Model.Name).js"></script>
To :
<script>>query in db by #(Model.Name) parameter to get corresponding jscontent</script>

Make it a controller/method and you can take advantage of things like caching, auth etc for free:
public class ScriptController
{
public ActionResult Content(MyModel model)
{
var result = "alert("Hello World!");";
return JavaScript(result);
}
}
JavaScriptResult
Then in your html:
<script src="~/Script/Content?prop1=whatever"></script>

Related

How to create consistent URLs with MVC .NET routing?

I am running ASP.Net MVC 5 in .NET Framework 4.8. I keep getting 404 error due to inconsistently generated URLs. For example, in my _PageNav.chstml partial that is included at the top of each page I the following to take the user back to the home page: #Url.Action("Index", new { controller = "Home" }). In the navigation bar this resolves to <a class="navbar-brand" href="/" /> and functions properly.
When I use the same #Url.Action("Index", new { controller = "Home" }) on the same page, but later in on a button, it resolves to this: <a id="doneButton" class="btn btn-secondary px-4" href="https://localhost:44337/smrt/">Done</a>
Because of this inconsistency I often have issues where AJAX JavaScript references to the controllers end up with missing controller references such as /create resulting in https://localhost:44337/create instead of https://localhost:44337/home/create or /home/create resulting in https://localhost:44337/home/home/create instead of https://localhost:44337/home/create
I do have also have some limitations because of security restrictions; for example I cannot have any JavaScript on the page itself so I can't write razor code in my .cshtml files that will result in JavaScript. I can only use JavaScript referenced in source files for the page.
#Url.Action("Index", "Home") should be enough to do the job but I've noticed some issues sometimes where custom routing is at play, when changing levels. The Url.Action routine does not render fully qualified urls and sometimes I found I had to append "../" to navigate to a different controller structure, when one controller's view makes an AJAX call to another folder's view. Also, the default URL structure can throw off relative URL calls because the default implementation is to hide /Index in the URL structure. So the URL:
localhost/site (defaults Home/Index)
localhost/site/other (defaults the Index)
Sees the two views in a different folder structure, and URL navigation can get thrown off.
That has been my experiences as to why you may see some of the problems you are seeing.
It took a few different ideas, but I was able to solve my problem. I now get consistent URLs in just they way I need them, every time.
First, I used this article How to Build Absolute Action URLs Using the UrlHelper Class, to create the follwoing class with an extension method based on the UrlHelper Class .
using System.Web.Mvc;
namespace MVCPages.Utilities
{
public static class UrlHelperExtenions
{
/// <summary>
/// Generates a fully qualified URL to an action method by using
/// the specified action name, controller name and route values.
/// </summary>
/// <param name="url">The URL helper.</param>
/// <param name="actionName">The name of the action method.</param>
/// <param name="controllerName">The name of the controller.</param>
/// <param name="routeValues">The route values.</param>
/// <returns>The absolute URL.</returns>
public static string AbsoluteAction(
this UrlHelper url,
string actionName,
string controllerName,
object routeValues = null
)
{
var httpContext = url.RequestContext.HttpContext;
string scheme = httpContext.Request.Url.Scheme;
return url.Action(
actionName,
controllerName,
routeValues,
scheme
);
}
}
}
This new method dynamically gives me the root of the website no matter where the site is deployed.
I then call the new method extension in the views where I need URL consistency and pass the absolute root URL to the view using the ViewBag.
public ActionResult Index()
{
string rootUrl = Url.AbsoluteAction("Index", "Smrt");
ViewBag.RootUrl = rootUrl;
}
Since I am not allowed to use Razor to create JavaScript, I next use Razor to create a hidden HTML div tag that includes the root URL, <div id="rootUrl">https://rooturl.com/</div>
Now, in JavaScript, I use the DOM to retrieve the URL from the HTML tag; then use ad that to my ajax calls to create a complete URL for the AJAX calls.
window.onload = function () {
var rootUrl = document.getElementById("rootUrl").innerHTML;
var ajaxUrl = rootUrl + ajaxCall;
};

Read in javascript a spring controller model

I have a controller where a JSONObject is passed as parameter. I would like to work with the object "all" in javascript (client side) not in the server side (JSP) so I don't want to get the object with JSP tags.
#RequestMapping(value = { "/dfi/rca" }, method = RequestMethod.GET)
public String getRcaResult(Model model, String flight_id) {
...
JSONObject all = new JSONObject ();
...
model.addAttribute("all",all);
return "dfi/rca";
}
I have a JSP file that import a Javasript file where I use the attribute all but I don't know how to access to it. If I use this code in the JSP file it works properly:
<script type="text/javascript">
var all= "${all}";
</script>
But if I try the same importing a Javascript file in the JSP, it doesn't get anything:
<script type="text/javascript" src="${pageContext.request.contextPath}/resources/js/all.js"></script>
In all.js:
var rcaresults = JSON.parse('${all}');
Are there any way to read the Spring model attributes in a Javascript file?
Thanks in advance.
JavaScript is run on the client side. Your model model.addAttribute("all",all); does not exist on the client side, it only exists on the server side while you are rendering your .jsp.
If you want data from the model to be available to client side code (ie. javascript), you will need to store it somewhere in the rendered page. For example, you can use your Jsp to write JavaScript assigning your model to JavaScript variables.
e.g <script>var paramOne =<c:out value="${all}"/></script>
when you use src, your browser (and not your backend) will try to fetch the javascript file from
"${pageContext.request.contextPath}/resources/js/all.js"
so the file is not processed by the server as a ModelView.

asp.net mvc another controller in the same folder

I have a folder 'Report' which holds ReportController.
Now i want to add AgreementController to the same folder.
from javascript i have a code which runs 'Download' action (downloads file).
When i run from javascript - Report/Download/id='5' everything fine.
When i run from javascript - Report/Agreement/Download/id='5' everything bad.
How can i run 'Download' action from Agreement controller ?
I dont want one folder-one controller structure.
I think only areas can help me there ?
according to routing:
url: "{controller}/{action}/{id}"
your code is:
Report/Agreement/Download/id='5'
so in your case:
Controller= Report
action= Agreement
Id= Download.
that's why you get an error
You need to remove Report from call end use this:
Agreement/Download/id='5'
If you are writing js in same view page and not in external js file, you can use mvc url.action in ajax call file method to call appropriate controller and action method as described below
syantax:
url: '#Url.Action("ActionMethodName","ControllerName",new {Parameters})'
In your case it would be something like this:
to invoke report controller's download method
url: '#Url.Action("Download","Report",new { id = "Value" })'
to invoke agreement controller's download method
url: '#Url.Action("Download","Agreement",new { id = "Value" })'
If you are using external js file then it will be as below
url: serverbaeurl + "/Report/Download?id=" + "Value"
url: serverbaeurl + "/Agreement/Download?id=" + "Value"
(here serverbaseurl will be the domain of website)
(you will have to add other ajax options as needed)

CakePHP, pass parameter to js.php file?

Im trying to use PHP to generate a javascript file. I have the file included and all scripts are workning in it. The think i cant figure out is how i pass a parameter to this file?
To pass a parameter from the controller to the view i use:
$this->set('object_models', $object_models);
To pass it from the view to a element i use:
echo $this->element('pageElement', array('object_model' => $object_model));
Im including my js.php file by adding it in the view with:
echo $this->Html->script('modelDrawer.js.php?', false);
Have you considered using parseExtensions and including your JS file as a view for a controller that you can perform logic on directly?
This would work similarly to the way rss feeds and xml files are generated with Cake.
See this article
UPDATE
Go to your routes.php file, and add the line Router::parseExtensions('js');
Then, create a controller called, for the sake of this, DynamicController.php - and paste this in there:
class DynamicController extends AppController {
public $uses = array();
public function modelDrawer() {
// logic in here
$this->set( 'object_models', $object_models );
}
}
Create a view folder and view file:
/app/View/Dynamic/js/model_drawer.ctp
In that model_drawer.ctp file, you can place your view/script logic that you want to be cakeified.
You can then call your script like this:
<script type="text/javascript" src="/dynamic/modelDrawer.js"></script>
Give that a try!

Build a Javascript Widget : can I call an aspx?

I'd like to create my own JS widget, which it must be dinamic.
I mean, for example, the html generated from the downloaded script :
<script src="www.mywebsite.it/widget/?ID=2&Category=4" type="text/javascript"></script>
must be different from :
<script src="www.mywebsite.it/widget/?ID=1&Category=5" type="text/javascript"></script>
and the Data into HTML should be taken from Database, on my server. So, I need to call an aspx page that create javascript that will create html? Or which could be the solution?
The better way is to use generic handler with .ashx, if you want retrieve data from server and send data in JSON or XML.
Next, the data will be inserted in page with javascript.
So, if I understand well, you do generate an .aspx that contains your template and a javascript that hold the code to navigate in Category as this if you use JQuery :
$.ajax({
url: 'data.ashx?ID=2&Category=5',
success: function(data) {
$('.result').html(data);
alert('Load was performed.');
}
});
Server behind (ashx) :
private readonly JavaScriptSerializer _js = new JavaScriptSerializer();
public void ProcessRequest(HttpContext context)
{
//Do logic and retrieve data here
Categorys c = GetFooById(context.Request["id"]);
context.Response.Write(_js.Serialize(c));
context.Response.ContentType = "application/json";
}
It seems that you'd want to use AJAX.
The script source shouldn't be dynamic (it can't be cached if it is), but the script itself could call whatever page you like to pull back data (say in JSON format) or raw markup to place in a pre-defined element.
Don't use the ASPX page to create javascript if you can help it.
Consider using a JavaScript library such as jQuery to help you.

Categories