ASP.Net OnGet - URL encoded Parameters - Only some parameters are Decoded by ASP.Net Framework - asp.net-core

Ola,
for some reason, it looks like ASP.Net Core Webserver (.Net 6) seems to url-decode some characters for the PageModel.OnGet Method and some characters are not url-decoded.
The request according URL in Internet Edge in the addressbar:
http://localhost:5000/ItemsOverview/Data/dm%3A%2F%2F%2Fxxx.ebs.data%3Fmetaclass%3Ddm%253A%252F%252F%252Fxxx.ebs%25232d73a22b-8505-4523-939d-7f524253f95b
This is what is sent to the OnGet Method:
ItemsOverview.cshtml: #page "/ItemsOverview/{workspace}/{extent}/{item?}"
ItemsOverview.cshtml.cs:
public void OnGet(string workspace, string extent, string? item)
{
Workspace = HttpUtility.UrlDecode(workspace);
Extent = HttpUtility.UrlDecode(extent);
Item = HttpUtility.UrlDecode(item);
}
The variable 'extent' as received by the debugger looks like the following:
dm:%2F%2F%2Fxxx.ebs.data?metaclass=dm%3A%2F%2F%2Fxxx.ebs%232d73a22b-8505-4523-939d-7f524253f95b
==> So, the server has changed %3F to '=' and %25 to '%', but not characters like %2F...
The url is generated by using the javascript function 'encodeURIComponent':
export function getLinkForNavigateToExtentItems(workspace: string, extentUri: string, parameter?: NavigationToExtentItemsParameter) {
let urlParameter = "";
let ampersand = '?';
if (parameter?.metaClass !== undefined) {
urlParameter += ampersand + "metaclass=" + encodeURIComponent(parameter.metaClass);
ampersand = '&';
}
return Settings.baseUrl + "ItemsOverview/" +
encodeURIComponent(workspace) + "/" +
encodeURIComponent(extentUri + urlParameter);
}
Expectation:
The OnGet Call is called with the parameter 'extent' is given in the Url by Browser.
Situation:
Some characters are already decoded by Browser(?) or ASP.Net Core Framework(?)

Resolved by:
public static string? DecodePath(string? pathToBeDecoded)
{
return pathToBeDecoded?
.Replace("%2F", "/")
.Replace("%2f", "/")
.Replace("%25", "#");;
}
I'm not convinced, but it seems to work.

Related

How to Evaluate JavaScript code from .NetCore

I need to evaluate Javascript code from .netcore 2.1 project
string vRule = "var input = arguments[0]; if (!input) return \"\"; if(input.length != 7) return \"a fixed string length of 7 is required\"; else return \"\"";
string spResponse = "sdfsd23";
string errorText =
_jscriptEval.EvalToString(new List<object>
{
"var args = new Array('" + spResponse +
"');\r\n validateRule(args);\r\n function validateRule(arguments){" + vRule +
"}\r\n"
});
You can use Jint. Jint implements the ECMA 5.1 spec and can be use from any .NET implementation (Xamarin, .NET Framework, .NET Core). Just use the NuGet package and has no dependencies to other stuff - it’s a single .dll and you are done!
Just transform your javascript code into a function and run it like this (this is just an example, not your implementation):
var engine = new Engine()
.Execute("function MyFunction(a, b) { return a + b; }")
;
engine.Invoke("MyFunction", 1, 2); // -> 3
You have more explanations and examples on https://github.com/sebastienros/jint

Making query params optional in IBM API Connect

Hi we are using IBM Api Connect as a gateway for our api's, i am unable to figure out how to make query params optional, i tried doing it in the DESIGN and ASSEMBLE sections of IBM api connect, but no luck.
this is my final URL that i want to invoke
www.testdomain.products/getProducts?param1 = " "& param2 = " " & param3 = " "
here all the params are optional i am giving this url as
www.testdomain.products/getProducts?param1=$(request.parameters.param1)&param2=$(request.parameters.param2) & param3=$(request.parameters.param3)
in one use case i am only passing param1, and want the final url to be constructed only with param1 but this is what i am seeing
www.testdomain.products/getProducts?param1="value"&param2=&param3=
what should i do so that the url is constructed with only the values that i am passing, like this
www.testdomain.products/getProducts?param1="value"
It looks like you just want to proxy the query string? In which case you can use $(target-url)$(request.search) as your invoke URL.
This can be achieved by creating the dynamic target URL using a script rather than setting static backend service URLin invoke/Proxy action.
Assembly section
Get GatewayScript Action before invoke
var targetUrl = "www.testdomain.products/getProducts?";
var input_param1 = apim.getvariable('request.parameters.param1');
var input_param2 = apim.getvariable('request.parameters.param2');
if(input_param1 !==null || input_param1 !="" || input_param1 != undefined ){
targetUrl = targetUrl.concat("param1="+input_param1))
}
if(input_param2 !==null || input_param2 !="" || input_param2 != undefined ){
if(targetUrl.indexOf('param1') > 0){
targetUrl = targetUrl.concat('&')
}
targetUrl = targetUrl.concat("param2="+input_param2))
}
apim.setvariable('target-url',targetUrl)
In Invoke/Proxy - Use this $(target-url)
There might be some syntax issue, but we can achieve using the above way. Thanks!

PUT blob with Blob Service API in Postman - Authorization header

I need help constructing the Authorization header to PUT a block blob.
PUT\n\n\n11\n\n\n\n\n\n\n\n\nx-ms-blob-type:BlockBlob\nx-ms-date:Sat, 25 Feb 2017 22:20:13 GMT\nx-ms-version:2015-02-21\n/myaccountname/mycontainername/blob.txt\n
I take this, UTF 8 encode it. Then I take my access key in my Azure account and HMAC sha256 this UTF 8 encoded string with the key. Then I output that in base64. Let's call this output string.
My authorization header looks like this: SharedKey myaccountname:output string
It is not working.
The header in Postman also has x-ms-blob-type, x-ms-date, x-ms-version, Content-Length, and Authorization. The body for now says hello world.
Can anyone help me make this successful request in Postman?
<?xml version="1.0" encoding="utf-8"?>
<Error>
<Code>AuthenticationFailed</Code>
<Message>Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.
RequestId:cdeb9a5e-0001-0029-5fb5-8f7995000000
Time:2017-02-25T22:22:32.0300016Z</Message>
<AuthenticationErrorDetail>The MAC signature found in the HTTP request 'jiJtirohvi1syXulqkPKESnmQEJI4GpDU5JBn7BM/xY=' is not the same as any computed signature. Server used following string to sign: 'PUT
11
text/plain;charset=UTF-8
x-ms-date:Sat, 25 Feb 2017 22:20:13 GMT
x-ms-version:2015-02-21
/myaccountname/mycontainername/blob.txt'.</AuthenticationErrorDetail>
</Error>
EDIT:
First, I want to thank you and everyone who responded. I truly truly appreciate it. I have one last question and then I think I'll be set!! I'm not using that code - I'm doing this all by hand. If I have my key: X2iiy6v47j1jZZH5555555555zzQRrIAdxxVs55555555555av8uBUNGcBMotmS7tDqas14gU5O/w== changed slightly for anonymity - do I decode it: using an online base64decoder. Then, when I have my string which now looks like this: PUT\n\n\n11\n\ntext/plain;charset=UTF-8\n\n\n\n\n\n\nx-ms-blob-type:BlockBlob\nx-ms-date:Mon, 27 Feb 2017 21:53:13 GMT\nx-ms-version:2015-02-21\n/myaccount/mycontainer/blob.txt\n so I run this in https://mothereff.in/utf-8 and then use this in HMAC with my decoded key: https://www.liavaag.org/English/SHA-Generator/HMAC/ - using sha256 and base64 at the end.
Is that how I get the correct string to put here?: SharedKey myaccount:<string here>
I believe there's an issue with how you're specifying StringToSign here:
PUT\n\n\n11\n\n\n\n\n\n\n\n\nx-ms-blob-type:BlockBlob\nx-ms-date:Sat,
25 Feb 2017 22:20:13
GMT\nx-ms-version:2015-02-21\n/myaccountname/mycontainername/blob.txt\n
If you notice the error message returned from the server, string to sign by server is different than yours and the difference is that the server is using Content-Type (text/plain;charset=UTF-8) in signature calculation while you're not. Please include this content type in your code and things should work just fine.
Here's the sample code (partial only) I used:
var requestMethod = "PUT";
var urlPath = "test" + "/" + "myblob.txt";
var storageServiceVersion = "2015-12-11";
var date = DateTime.UtcNow.ToString("R", CultureInfo.InvariantCulture);
var blobType = "BlockBlob";
var contentBytes = Encoding.UTF8.GetBytes("Hello World");
var canonicalizedResource = "/" + accountName + "/" + urlPath;
var canonicalizedHeaders = "x-ms-blob-type:" + blobType + "\nx-ms-date:" + date + "\nx-ms-version:" + storageServiceVersion + "\n";
var stringToSign = requestMethod + "\n" +
"\n" + //Content Encoding
"\n" + //Content Language
"11\n" + //Content Length
"\n" + //Content MD5
"text/plain;charset=UTF-8" + "\n" + //Content Type
"\n" + //Date
"\n" + //If - Modified - Since
"\n" + //If - Match
"\n" + //If - None - Match
"\n" + //If - Unmodified - Since
"\n" + //Range +
canonicalizedHeaders +
canonicalizedResource;
string authorizationHeader = GenerateSharedKey(stringToSign, accountKey, accountName);
private static string GenerateSharedKey(string stringToSign, string key, string account)
{
string signature;
var unicodeKey = Convert.FromBase64String(key);
using (var hmacSha256 = new HMACSHA256(unicodeKey))
{
var dataToHmac = Encoding.UTF8.GetBytes(stringToSign);
signature = Convert.ToBase64String(hmacSha256.ComputeHash(dataToHmac));
}
return string.Format(CultureInfo.InvariantCulture, "{0} {1}:{2}", "SharedKey", account, signature);
}
According to your error message, it indicates that authorization signature is incorrect.
If the Content-Type "text/plain; charset=UTF-8" is not included in the header, please add it in the stringTosign and postman.
When we try to get the signature, we need to make sure the length of the blob.txt matches the Content length in the stringTosign. That means request body length should match the content length in the stringTosign.
I test it with Postman, it works correctly. We can get the signature with the code in another SO Thread. The following is my detail steps
Add the following header
Add the request body (example: Hello World)
Send the put blob request.
Update :
Please have a try to use the online tool to generate signature for test.

Fiddler script to automatically save response body

I need help writing a script for fiddler. What I need is to automatically save a certain response body every time it comes up in the session window.
I have tried to follow the instructions in this post Fiddler Script - SaveResponseBody() but I just get an error when I try and save CustomRules.js. (I could be inserting in wrong or in the wrong place)
I am new to fiddler and scripts so any help here would be greatly appreciated.
I have tried adding this:
static function OnBeforeResponse(oSession: Session) {
if(oSession.url.EndsWith(".png")) {
oSession.SaveResponseBody(); //Actual content of OnBeforeResponse function.
}
}
and then adding this:
if ((oSession.responseCode == 200) &&
oSession.oResponse.headers.ExistsAndContains("Content-Type", "image/png")) {
SaveResponseBody("C:\\temp\\" + oSession.SuggestedFilename);
}
to the CustomRules.js script.
SaveResponseBody is a method on the oSession object.
oSession.SaveResponseBody("C:\\temp\\" + oSession.SuggestedFilename);
Be sure to add your code within OnBeforeResponse(oSession: Session) { ... } function
The following code will save the request and response body of any url that contains "procedimentoservice" and a response code that differs from OK (200).
if (oSession.PathAndQuery.ToLower().Contains("procedimentoservice"))
{
if(oSession.responseCode != 200)
{
var directory2 = "C:\\log\\NEXT\\";
var filename2 = oSession.oRequest.headers['SOAPAction'].ToString().Replace('"','') + "_" + Guid.NewGuid();
var path2: String = System.IO.Path.Combine(directory2, filename2);
oSession.SaveRequestBody(path2 + "_request.txt");
oSession.SaveResponseBody(path2 + "_response.txt");
}
}
File names will be in the following format:
c:\log\NEXT\CriarEvento_fa15709e-b2a8-402d-a623-e4f01e6e8ae1_request.txt
c:\log\NEXT\CriarEvento_fa15709e-b2a8-402d-a623-e4f01e6e8ae1_response.txt
c:\log\NEXT\CriarEvento_ff650cf8-8fe6-47a2-8552-a4d8bce246f3_request.txt
c:\log\NEXT\CriarEvento_ff650cf8-8fe6-47a2-8552-a4d8bce246f3_response.txt

SharePoint 2010 Wiki Template Script Issue

I'm looking for a way to give my SharePoint users a way to create new wiki pages from an existing template. In the process of researching I found a great walkthrough that seems to fit the need (http://www.mssharepointtips.com/tip.asp?id=1072&page=2), but I'm having trouble getting it to work. The problem seems to lie in the assignment of a path to PATHTOWIKI-- if I use "/Weekly Update Wiki", the script returns an error of "There is no Web named '/Weekly Update Wiki'." If I use "Weekly Update Wiki" without the forward slash, I instead get an error of "There is no Web named '/sites/[parentSite]/[childSite]/Weekly Update Wiki/Weekly Update Wiki'."
Any ideas about what I'm not understanding here?
function myCreateProject() {
// Configure these for your environment
// include no slashes in paths
var PATHTOWIKI = "Weekly Update Wiki";
var PATHTOPAGES = "Pages";
// file name only for template page, no extension
var TEMPLATEFILENAME = "Template";
var myPathToWiki = encodeURIComponent(PATHTOWIKI);
var myPathToPages = PATHTOPAGES + "%2f";
var myTemplateFileName = encodeURIComponent(TEMPLATEFILENAME) + "%2easpx";
var EnteredProject = document.getElementById("NewProjName");
var myNewName = EnteredProject.value;
if(myNewName == "") {
alert('Please enter a name for the new project page');
} else {
myNewName = encodeURIComponent(myNewName) + "%2easpx"
$.ajax({
url: PATHTOWIKI + "/_vti_bin/_vti_aut/author.dll",
data: ( "method=move+document%3a14%2e0%2e0%2e4730&service%5fname="
+ myPathToWiki +
"&oldUrl=" + myPathToPages + myTemplateFileName +
"&newUrl=" + myPathToPages + myNewName +
"&url%5flist=%5b%5d&rename%5foption=nochangeall&put%5foption=edit&docopy=true"
),
success: function(data) {
var rpcmsg1 = getMessage(data, "message=", "<p>");
$("#myInfo").append("<br />" + rpcmsg1);
if(rpcmsg1.indexOf("successfully") < 0) {
// get error info
var rpcmsg2 = getMessage(data, "msg=", "<li>");
$("#myInfo").append("<br />" + rpcmsg2 + "<br />");
} else {
$("#myInfo").append("<br />Go to new page<br />");
}
},
type: "POST",
beforeSend: function(XMLHttpRequest) {
XMLHttpRequest.setRequestHeader("X-Vermeer-Content-Type",
"application/x-www-form-urlencoded");
}
});
}
}
Update: I figured out what needed to happen in my case. Since I couldn't get a grasp on the relative approach, I just went with the absolute path for PATHTOWIKI and slightly modified the append in the ajax call.
PATHTOWIKI:
var PATHTOWIKI = "https://[domain]/sites/[parentSite]/[childSite]";
append:
$("#myInfo").append("<br />Go to new page<br />");
The change in the latter line of code is subtle; since I used an absolute path in PATHTOWIKI, I just removed the leading forward slash in the anchor tag, so that <a href=\"/" became <a href=\"". This renders the script slightly less portable, but since it's a one-off effort I'll stick with this unless anything comes along to expand the scope.