ASP.net MVC - Action Does not like JSON string 400 Bad Request - javascript

I have an action that takes 2 strings. One of the strings is a big, ugly json string. I suspect that the action will not allow the special characters to be passed because I keep getting a 400 - Bad Request.
Can a serialized json object be passed to an action?
public ActionResult SaveState(string file, string state)
{
string filePath = GetDpFilePath(file);
HtmlDocument htmlDocument = new HtmlDocument();
htmlDocument.Load(filePath);
HtmlNode stateScriptNode =
htmlDocument.DocumentNode.SelectSingleNode("/html/head/script[#id ='applicationState']");
stateScriptNode.InnerHtml = "var applicationStateJSON =" + state;
htmlDocument.Save(filePath);
return null;
}
ClientScript
'e' is a large json string
$.post('/State/SaveState/' + fileName+'/' + '/' + e + '/');
strong text
I am now encoding the text using UriEncoding() but it makes no difference. I don't think that MVC Actions allow me to send these special characters by default.. is that true? How do you work around this?
$.post('/State/SaveState/' + encodeURIComponent(fileName) + '/' + '/' + encodeURIComponent(e) + '/');
Sample request:
Request URL:http://localhost:51825/State/SaveState/aa6282.html//%7B%22uid%22%3A%22testUser%22%2C%22a

You need to encode it when the request is made:
$.post('/State/SaveState/' + encodeURIComponent(fileName) + '/' + encodeURIComponent(e));

Yes, serialized JSON object can be passed to an action method. MVC3 makes this even easier with built-in JSON binding. I use the json2 library to serialize the objects. See this post for more details. Works really great.
http://haacked.com/archive/2010/04/15/sending-json-to-an-asp-net-mvc-action-method-argument.aspx

Because I am send this data to the sever and the size of the string I am sending is large. I really should be sending the data in the post body.
It seems that there is also a limitation on the amount of data that you can send via the query string. I cannot be certain that this was the source of the error message but it certainly would make sense. In case the following post works correctly:
$.post('/State/SaveState/', { file: fileName, state: e });

You probably need to HTML-encode e before you add it to the URL. Also, you have an extra / that you don't need.

Related

How to send getJSON a string with special characters?

I want to send a getJSON with special characters?
In this case i have a .js file which create the string to send using getJSON methos. for that i use following command.
$.getJSON(strUrl, UI_DesignPecTab.validateResponse);
Using above method i need to send a string like follows :
var ID = "W6"
var headerString = "PT##?" + ID + "Z##;#TKT/#CHK/#BOR/";
But when i send this to server side it fails due to this uri contains some invalid characters? I need to know how can i get this done. I have tried to encode and send this using "encodeURIComponent()" but um not sure is it correct or not? if it correct how to decode it server side in java? For the above method i have used following code:
headString = URLDecoder.decode(pecTabData.getHeadString(), "UTF-8");

encodeURIComponent Not Working with Web API Call

I'm getting a 404 Not Found when making this call:
var url = rootWebApiUrl + '/folders/' + $scope.selectedServer.Name + "/" + serviceName;
$http.get(url) // the rest of this line doesn't matter for this issue
I thought that maybe using encodeURIComponent would help, but I get the same 404 Not Found error:
var url = rootWebApiUrl + '/folders/' + $scope.selectedServer.Name + "/" + encodeURIComponent(serviceName);
This is the Web API Method Signature:
[Route("folders/{serverName}/{serviceName}")]
[HttpGet]
public IEnumerable<Folder> Folders(string serverName, string serviceName)
The first option (above) works if I change the service name while debugging. The original service name is Company Name Message Bus Manager 3.6 - MesFinishingEvents. If I change it to something with no spaces, like snuh, then the Web API call succeeds and I can debug in the Web API method.
How can I pass the original service name in my $http.get(url) call?
Edit: URL values:
With service name that has spaces:
http://localhost:4153/api/services/folders/ServerName/Company%20Name%20Message%20Bus%20Manager%203.6%20-%20MesFinishingEvents
Using a simple service name:
http://localhost:4153/api/services/folders/ServerName/snuh
WebAPI controllers struggle when you have a . in your parameters, here and here.
Your method call would work all the way up to:
http://localhost:4153/api/services/folders/ServerName/Company%20Name%20Message%20Bus%20Manager%203
and beyond, if the period didn't exist.
The quickest solution is to add a trailing slash. The longer solution would be to modify your sites HTTP handlers in IIS.

Iteratively obtaining different pages of a query using python

I am trying to parse a sequence of html pages using python, I am having trouble grabbing the pages in iterative fashion. The link to the web page.
Milano Library
After peeking through the source, I found a function that responds to the click event on button element for the next page.
function SaltaAPagina() {
var CalcPag = VAIAPAGINA.value;
if (CalcPag > 0) {
CalcPag=CalcPag;
}
else {
CalcPag="1";
}
document.location = "/OPACMI01/cat/SDW?W=CODICE_BIBLIO+%3D+%27LO1+01%27+AND+EDITORE+PH+WORDS+%27sonzogno%27+AND+DATA_PUBBLICAZIONE+%3C+1943+ORDER+BY+ORDINAMENTO/Ascend&M=" + CalcPag + "&R=Y";
}
I know that I can encode parameters using pythons urllib2 module using the urlencode method. But I am not sure what I should be including as a parameter
lomba_link='http://www.biblioteche.regione.lombardia.it/OPACMI01/cat/SDW?W%3DCODICE_BIBLIO+%3D+%27LO1+01%27+AND+EDITORE+PH+WORDS+%27sonzogno%27+AND+DATA_PUBBLICAZIONE+%3C+1943+ORDER+BY+ORDINAMENTO/Ascend%26M%3D1%26R%3DY'
params = urllib.urlencode([('CalcPag',4)])
# this has not worked.
req = urllib2.Request(lomba_link)
print req
response = urllib2.urlopen(req,params)
html_doc = response.read()
What am I missing here?
Thanks
The javascript function you posted is passing several parameters to the target page:
document.location = "/OPACMI01/cat/SDW" + // This is the path of the page
"?W=CODICE_BIBLIO+%3D+%27LO1+01%27+AND+EDITORE+PH+WORDS+%27sonzogno%27+AND+DATA_PUBBLICAZIONE+%3C+1943+ORDER+BY+ORDINAMENTO/Ascend" + // The first parameter
"&M=" + CalcPag + // The second parameter
"&R=Y"; // The third parameter
In your code, you've encoded all of the & and = symbols in the URL, so you're passing a single, long parameter with no value - changing those symbols back to what they were in the javascript function should do the trick.
lomba_link='http://www.biblioteche.regione.lombardia.it/OPACMI01/cat/SDW'
params = urllib.urlencode([
('W', 'CODICE_BIBLIO+%3D+%27LO1+01%27+AND+EDITORE+PH+WORDS+%27sonzogno%27+AND+DATA_PUBBLICAZIONE+%3C+1943+ORDER+BY+ORDINAMENTO/Ascend'),
('M', 4),
('R', 'Y')
])
It's much easier to work with the brilliant requests library, rather than the urllib2 library...
In regards to urllib2.urlopen the params is for POST requests. Unfortunately you need to append the query string to the url to make a GET request.
eg:
req = urllib2.urlopen(req + '?' + params)
With requests, this would be much simpler:
page = requests.get(some_url, params={'CalcPag': '4'})

How do I URL Encode a URL parameter that is itself a URL?

Quick background -
I am making a jQuery ajax call to a service I wrote that returns a JSON response. The service accepts a web site URL (i.e. www.google.com, www.xyz.com/abc123). The format of the request is as follows:
http://www.mysite.com/[url]
... where [url] is a user provided URL (again, something like www.google.com/abc)
I need to URL encode the parameter, as mysite.com/www.google.com is giving me errors.
My problem is, all of the standard javascript encoding functionality does not actually encode the URL.
An example:
<html>
<head>
<script>
document.write("encodeURIComponent = " + encodeURIComponent("www.google.com") + "<br />");
document.write("encodeURI = " + encodeURI("www.google.com") + "<br />");
document.write("escape = " + escape("www.google.com"));
</script>
</head>
<body>
</body>
... has the following output:
encodeURIComponent = www.google.com
encodeURI = www.google.com
escape = www.google.com
What is the proper way to achieve this using JavaScript/jQuery?
I don't think it's relevant, but just in case, this is a Rails 3.0.7 app.
EDIT FOR MORE DETAIL
If www.google.com is already URL encoded, and periods are fine in my URL (www.mysite.com/www.google.com), why am I getting this error?
From Chrome Dev Tools:
GET http://localhost:3000/s/www.google.com 404 (Not Found)
My jQuery snippet:
$.getJSON("http://localhost:3000/s/" + encodeURI($("#txtURL").val()), function(data) {
alert(data.result.url);
});
This is a perfectly valid URL:
http://mysite.com/s/www.google.com
I suspect that you're just running into the Rails format stuff (i.e. .html at the end of the URL sets the format to HTML, .js for JSON, ...) so you just need to fix your route to keep the format auto-detection from getting in the way:
map.connect '/s/:url', :requirements => { :url => /.*/ }, ...
or
match '/s/:url' => 'pancakes#house', :constraints => { :url => /.*/ }, ...
or whatever routing syntax you're using.
If you don't tell rails that the :url should match /.*/ (i.e. anything at all), it will try to interpret the periods in the route as format specifiers, that will fail and Rails will 404 because it can't figure out how to route the URL.
URL encoding escapes characters that have a special meaning in the URL (like / and ?) and/or aren't ASCII characters. http://mysite.com/www.google.com is a perfectly valid URL, there's nothing to escape. If you'd include the protocol as well, you'd get some escape-worthy characters:
encodeURIComponent('http://www.google.com')
"http%3A%2F%2Fwww.google.com"
If your server 404s on a request to http://localhost:3000/s/www.google.com, that means the URL isn't handled by the server. It doesn't mean that the URL is invalid.
As mu said dots don't need to be encoded.
The jQuery-way for building a proper QUERY_STRING would be the use of $.param()
$.param({encodeURIComponent:'http://www.google.de'})

Encode string javascript so that it can be transmitted to a server

I'm trying to send json string in the get request to the server, here is how it looks before encoding :
filters={"groupOp":"AND","rules":[{"field":"countrycode","op":"eq","data":"ARG"}]}
Naturally I end up with null pointer when trying to get this json string, then I googled this encodeURIComponent and it partially encodes this string like this :
filters={"groupOp"%3A"AND"%2C"rules"%3A[{"field"%3A"countrycode"%2C"op"%3A"eq"%2C"data"%3A"ARG"}]}
But this is how it supposed to be in order to work :
filters=%7B%22groupOp%22%3A%22AND%22%2C%22rules%22%3A%5B%7B%22field%22%3A%22countrycode%22%2C%22op%22%3A%22eq%22%2C%22data%22%3A%22ARG%22%7D%5D%7D
How do I get this, entirely encoded string so I can read it at server side properly ?
Reason why I used get instead of post
I'm sending this filter(json) content to the server side, web service gets data from the database and returns pdf document.
Using post, I'm able to send correct data and the response is successfully displayed in my firebug console. But I need to return pdf doc to override the current page or open new window/tab and return in that one.
I think you're overworking this problem. Or encoding too many times. Or something.
You've got a JSON string, and you are trying to JSON encode it. That seems...unhelpful.
A better approach might be to produce a Javascript object, then JSON.Stringify that, and then transmit it as a parameter.
var thing = {
groupOp : "AND",
rules : [
{ field : "countrycode", op : "eq", data : "ARG" },
...
],
...
};
var stringrep = JSON.stringify(thing);
// post via jQuery
$.ajax({
type: 'POST',
url: url,
data: stringrep,
dataType: 'json'
success: function() { ... },
});
Normally for a JSON stringified message to or from the server, you'd want to use HTTP POST. HTTP GET puts all "parameters" in the URL; there is no message body. In contrast, HTTP POST allows you to attach a message body to the HTTP message, which can be "anything". With that approach, you don't need to url-encode the quotes and spaces; the JSON message just gets transmitted as the message body of the HTTP message.
HTTP POST is the way applications upload images, or transmit XML documents, and so on. Anything complex gets transmitted via POST.
var filtersParameter = 'filters=' + encodeURI(JSON.stringify(filters));
var filtersParameter = 'filters=' + atob(JSON.stringify(filters));
Note: atob() method uses base64 algorithm to encode the data. This encoded data can be easily passed to a server where it can be decoded using corresponding decoding methods (in python base64.b64decode(encoded_string) is used).

Categories

Resources