error in MVC, when I pass as parameter '&' fails - javascript

I have an error in MVC, when I pass as parameter '&' fails to come the following. How will I show in this example?
public IActionResult Create(int? idTrabalhador, [FromQuery]string GridState{}
view
var lnk = "#Url.Action("Create" , new { idTrabalhador = "{#KeyTrabalhador}", GridState = "{#GRID_STATE}" })";
lnk = lnk.replace(encodeURIComponent("{#KeyTrabalhador}"), 0);
lnk = lnk.replace(encodeURIComponent("{#GRID_STATE}"), JSON.stringify(state));
http://localhost:58185/TrabalhadorPincodes/Create?idTrabalhador=0&GridState={"filter":{"NomeTrabalhador":"nuno","Estado":"0"},"sorter":[],"currentPage":0}
model =>
GridState = "{\"filter\":{\"NomeTrabalhador\":\"nuno\",\"Estado\":\"0\"},\"sorter\":[],\"currentPage\":0}"
Perfect!!!
BUT
http://localhost:58185/TrabalhadorPincodes/Create?idTrabalhador=0&GridState={"filter":{"NomeTrabalhador":"&","Estado":"0"},"sorter":[],"currentPage":0}
model =>
GridState = "{\"filter\":{\"NomeTrabalhador\":\""
need help!!!

The browser is interpreting the & as part of the url as you are sending the http request via the GET method.
One method to handle this is to urlEncode your parameters using Server.UrlEncode
This also means you will need to decode the parameters within your controller.
The other solution is to post the values so that they are not part of the url but you will need to decide whether this is appropriate.

because the 'encodeURIComponent' only works in plain text, what I'm doing is creating a compound object soon does not work. I have to use the 'encodeURIComponent' as soon as the object is constructed not after it is built
filter.NomeTrabalhador = encodeURIComponent($('#NomeTrabalhador').val());

Related

Getting data from a .cs file to a .cshtml

I'm trying to pass the data received from my function to a .cshtml file that uses javascript.
public static int LastID()
{
int LastArticleNr;
SqlConnection conn = GetSqlConnection(null);
conn.Open();
LastArticleNr = conn.QueryFirstOrDefault <int> ("SELECT CAST(isnull(last_value,0) AS INT) AS ID FROM sys.identity_columns WHERE object_id = OBJECT_ID('Artikel')");
conn.Close();
return LastArticleNr;
}
Now I don't know whether this is possible or not, or whether I would need to use a different method of getting this data. However what I've tried is simply calling the function which, to probably no-ones surprise didn't do much. I've also tried this:
#using namespace.Classes.DataLayer;
#{
var LastID = DataLayer.LastID();
}
However even if the using clause should include the class in which this function exists, it fails to recognise the DataLayer class.
It really depends on how your application is structured. Like: What error do you get when you try to access the Data Access Layer?
But If this is being done on page load, you could pass the data into TempData:
TempData['LastId'] = LastID();
And then in your razor page:
#{
var lastId = TempData['LastId'];
}
However if you wanted to get it at any time after the page has loaded and do not want to refresh the page, you would have make an ajax call

How to access IMemoryCache from C# and Javascript

I stored values in my cache using my Controller class using the dependency IMemoryCache. I am also accessing my cache and get few values from it like so:
//IMemoryCache initailized before this variable : _cache
public void foo()
{
var token = _cache.Get<TokenModel>("Token" + HttpContext.Session.GetString("TokenGuid"));
//Do something with token
}
Question is:
How can I can access the cache from my Javascript file?
Cache is located on the server while JavaScript is executed on the client. The only way I can think of is if you create a cache controller and create a Get action on it. After that you would call this action in Ajax and asynchronously get the server cache value.
public class CacheController : Controller
{
[HttpGet("{key}")]
public IActionResult GetCacheValue(string key)
{
var cacheValue = //get your cache
return Json(cacheValue);
}
}
IMemoryCache allows you to speed up your application by storing your data "in-memory". So you can reach memory from your javascript code.
Please have a look to the documentation of the IMemoryCache here: https://learn.microsoft.com/en-us/aspnet/core/performance/caching/memory?view=aspnetcore-2.1
What I would suggest you is get your cached data on backend side and put it cookie. Then later you can get cookie value from your javascript code.
I assume you have an instance of IMemoryCache which name is _cache.
You can set cache by like this.
_cache.Set(cacheKey, cacheEntry, cacheEntryOptions);
HttpCookie myCookie = new HttpCookie("yourCookieName");
myCookie["cacheData"] = cacheEntry;
myCookie.Expires = DateTime.Now.AddDays(1d);
Response.Cookies.Add(myCookie);
or you can do the same after you get your cached data. Just get the data from your memory and set it to cookie.
You can get the cookie from your Javascript by using both DOM or JQuery.
If you would like to use DOM:
var x = document.cookie;
For jquery have a look at this answer on StackOverFlow:
https://stackoverflow.com/a/1599367/1261525

Embed javascript Variable within ASP.NET MVC 2 tag

I have a Javascript statement in an MVC view that looks like this and works:
win.attachURL('<%: Url.Action("GraphDetails", "Dashboard", new { area = "Anglian", OSName = "Hello" }) %>');
When I try to extract the variable 'Hello' and put it into a javascript variable (id) and subsequently embed it into my tag like this, it breaks:
var id = "Hello";
win.attachURL('<%: Url.Action("GraphDetails", "Dashboard", new { area = "Anglian", OSName = "' + id + '" }) %>');
Question is, how do I embed a JS variable inside an ASP server tag, that itself is already embedded within Javascript? This is for a local prototype, security concerns are not an issue.
Thank you,
Tom.
One is server-side, the other is client-side, you can't mix the two.
When you do it on the server side with the id as a variable it will break because id doesn't exist in the server side context.
Why don't u try break up the statement on the client side?
var id = "Hello";
var actionInit = "<%: Url.Action("GraphDetails", "Dashboard", new { area = "Anglian"}) %>";
win.attachURL(actionInit + "?OSName=" + id");
Note: when appending ?OSName, this may cause some issue if your route doesn't map 100% correctly. eg. u get /Dashboard/GraphDetails?area="Anglian" and u append another "?" that will be an invalid URL. On the other hand, it will also be invalid if your route matches 100% and you append "&OSName". So just check that out first
I don't think you can in general. In this case at least the <%: ... %> part is evaluated at page load time and will never run again.
Instead, you can compute this in JavaScript, e.g.
var id = "Hello";
var baseURL = '<%: Url.Action("GraphDetails", "Dashboard",
new { area = "Anglian" }) %>';
win.attachURL(baseURL + '&OSName=' + id);
However that makes assumptions about how you're assembling your routing parameters for that route. You could use Url.Action to generate the full route with a dummy value and then substitute, e.g.
var id = "Hello";
var baseURL = '<%: Url.Action("GraphDetails", "Dashboard",
new { area = "Anglian", OSName="ZZZ" }) %>';
win.attachURL(baseURL.replace('ZZZ', id);
but then there's a subtle chance this could go wrong, particularly if you're feeding user generated string into other parameters in the string where they could hit on the value you substitute.
If you really did want to run Url.Action again you'd have to make an AJAX call back to a known URL with the parameters to get the URL, which is overkill really.

AJAX post JSON data from Javascript to Grails

I'm trying to POST JSON formatted data from Javascript (using Prototype) to Grails. My Javascript code is:
var JSONObject = new Object;
JSONObject.id = "23";
JSONObject.name = "Test 1";
JSONstring = JSON.stringify(JSONObject);
var url = "${createLink(controller:'testController', action:'receiveJson')}";
new Ajax.Request(url, {
method:'post',
contentType:'application/json',
parameters:JSONstring,
asynchronous:true,
onSuccess: function (req) {
sendInfoResponse(req.responseText);
}
});
and the code in my Grails controller is:
def receiveJson = {
def json = request.JSON;
}
However, the 'json' variable appears to be empty in my tests. I'd be so grateful if someone could explain what I'm doing wrong. Many thanks.
In your Ajax.Request options change
parameters:JSONstring,
to
postBody:JSONstring,
The problem with using parameters is that it URL encodes the data so that the request body ends up looking like this:
%7B%22id%22%3A%2223%22%2C%22name%22%3A%22Test%201%22%7D&_=
Instead of the desired (which is what you get with postBody):
{"id":"23","name":"Test 1"}
Good question mfloryan - I was doing the testing manually, i.e. not as part of a unit or integration test.
Thanks very much for the help hvgotcodes. I made the changes to my code as you have suggested, but unfortunately to no avail. Interestingly, if I print request.JSON I get {}, whereas if I print request.json I get null.
EDIT: By 'printing' I mean using: request.JSON.toString()
EDIT: Thank you all so much for the help. Once I'd made the final change John Wagenleitne suggested the code began working properly. I'm very grateful indeed for all your help.
I don't think you are invoking the Ajax.Request correctly. From the documentation, the parameters option:
"The parameters for the request, which will be encoded into the URL for a 'get' method, or into the request body for the other methods. This can be provided either as a URL-encoded string or as any Hash-compatible object (basically anything), with properties representing parameters."
I think you need to do something like
...
parameters: {json: JSONString}
...
and then in your controller
request.json
note the form of the parameters object literal - it tells the Prototype library to make the request key 'json' and the request value be the json string. You access the key off the request object in the controller.
EDIT -- I just realized you're javascript block is jacked up.
This:
var JSONObject = new Object;
should be something like
var JSONObject = new Object();
...
you might also be able to do just an object literal, so
var jsonObject = {};
....

Best way to escape characters before jquery post ASP.NET MVC

I am semi-new to ASP.NET MVC. I am building an app that is used internally for my company.
The scenario is this: There are two Html.Listbox's. One has all database information, and the other is initally empty. The user would add items from the database listbox to the empty listbox.
Every time the user adds a command, I call a js function that calls an ActionResult "AddCommand" in my EditController. In the controller, the selected items that are added are saved to another database table.
Here is the code (this gets called every time an item is added):
function Add(listbox) {
...
//skipping initializing code for berevity
var url = "/Edit/AddCommand/" + cmd;
$.post(url);
}
So the problem occurs when the 'cmd' is an item that has a '/', ':', '%', '?', etc (some kind of special character)
So what I'm wondering is, what's the best way to escape these characters? Right now I'm checking the database's listbox item's text, and rebuilding the string, then in the Controller, I'm taking that built string and turning it back into its original state.
So for example, if the item they are adding is 'Cats/Dogs', I am posting 'Cats[SLASH]Dogs' to the controller, and in the controller changing it back to 'Cats/Dogs'.
Obviously this is a horrible hack, so I must be missing something. Any help would be greatly appreciated.
Why not just take this out of the URI? You're doing a POST, so put it in the form.
If your action is:
public ActionResult AddCommand(string cmd) { // ...
...then you can do:
var url = "/Edit/AddCommand";
var data = { cmd: cmd };
$.post(url, data);
... and everything will "just work" with no separate encoding step.
Have you tried using the 'escape' function, before sending the data? This way, all special characters are encoded in safe characters. On the server-side, you can decode the value.
function Add(listbox) { ...
//skipping initializing code for berevity
var url = "/Edit/AddCommand/" + escape(cmd);
$.post(url);
}
use javascript escaping, it does urlencoding.
Javascript encoding
Then in C# you can simple decode it.
It will look as such
function Add(listbox) { ...
//skipping initializing code for berevity
var url = "/Edit/AddCommand/" + escape(cmd);
$.post(url);
}
Have you tried just wrapping your cmd variable in a call to escape()?
You could pass the details as a query string. At the moment I'm guessing you action looks like:
public virtual ActionResult AddCommand( string id )
you could change it to:
public virtual ActionResult AddCommand( string cmd )
and then in you javascript call:
var url = "/Edit/AddCommand?cmd=" + cmd;
That way you don't need to worry about the encoding.
A better way would be if you could pass the databases item id rather than a string. This would probably be better performance for your db as well.

Categories