Part of my base url is removed upon adding a relative path - c#

I have a base url https://dev.services.com/this/is/nothing/
and the path "max/status"
When I try to add "max/status" to the base url the part this/is/nothing/ is removed. This just happens some times not always.
I am doing this:
IRestClient _builder;
var baseUrl = "https://dev.services.com/this/is/nothing/";
var nextUrl = "max/status";
var fullUrl = new Uri(baseUrl, nextUrl);
var client = new _builder.Build(fullUrl);
the result should be https://dev.services.com/this/is/nothing/max/status
but now is: https://dev.services.com/max/status
so, obviously I am getting an error because https://dev.services.com/this/is/nothing/max/status does not exist.
any idea?

Your code sample would not compile in its current form. To achieve your desired result, you'd need to change it like this:
var baseUrl = new Uri("https://dev.services.com/this/is/nothing/");
var fullUrl = new Uri(baseUrl, "max/status");

Related

Nethereuem SendTransactionAsync from my C# Web API fails with transaction type not supported: eth_sendRawTransaction

I'm working on integrating Nethereum into my .NET 5 C# API and can do read queries against my chosen blockchain (BSC), but cannot get a SendTransactionAsync or SendRequestAsync to successfully execute. I'm consistently getting the following exception:
Nethereum.JsonRpc.Client.RpcResponseException: 'transaction type not supported: eth_sendRawTransaction'.
Here are code snippets of what I have tried:
// Setup
var account = new Account(privateKey, chainId);
var rpcUrl = "https://data-seed-prebsc-2-s2.binance.org:8545/";
var client = new RpcClient(new Uri(rpcUrl));
var web3 = new Web3(account, client);
var mediaTokenAddress = "0x1E4d1BFDa5d55C2176E9E3e8367BAe720525a8e0";
var mtSvc = new MediaTokenService(web3, mediaTokenAddress);
var mintMsg = new MintNftFunction
{
FromAddress = account.Address,
Recipient = "REDACTED",
MetadataHash = "TestMetaDataHash",
MediaHash = "TestMediaHash",
SeasonId = 1
};
// Attempt #1: Using C# classes generated by the Nethereum CodeGen library
var txReceipt = await mtSvc.MintNftRequestAndWaitForReceiptAsync(mintMsg);
// Attempt #2
var txHandler = web3.Eth.GetContractTransactionHandler<MintNftFunction>();
var signedTx = await txHandler.SignTransactionAsync(mediaTokenAddress, mintMsg);
var txReceipt = await web3.Eth.Transactions.SendTransaction.SendRequestAsync(signedTx);
// Attempt #3
var txInput = mintMsg.CreateTransactionInput(mediaTokenAddress);
var txReceipt = await web3.Eth.TransactionManager.SendTransactionAsync(txInput);
Is there a configuration step I'm missing? Any help is appreciated!
EDIT: I want to call a contract method that will change values within the contract, rather than sending currency. So I need help figuring out how to do that.
For those that come across this issue, I resolved it by setting the following flag on my web3 instance:
web3.TransactionManager.UseLegacyAsDefault = true;
If there is a way to do what I need without setting this flag, please feel free to leave a comment.
Here is an example of how I do this with Nethereum
var web3 = new Nethereum.Web3.Web3("YOUR_NODE_ADDRESS");
var privateKey = "someprivatekey";
var senderAddress = "0x..."; // put actual sender address
var receiveAddress = "0x..."; //put actual receiver address
var txCount = await web3.Eth.Transactions.GetTransactionCount.SendRequestAsync(senderAddress);
double sendAmount = 5.09540000; //this is ETH
var amountInWei = Web3.Convert.ToWei(sendAmount);
//600 GWEI = 0.000000600
//60 GWEI = 0.000000060
var gwei = 147; // this is 0.000000147 ETH. You will want to calculate this based on network fees
var gasPrice = Web3.Convert.ToWei(0.000000001 * gwei);
var gasLimit = Web3.Convert.ToWei(0.000000000000021);
var encoded = Web3.OfflineTransactionSigner.SignTransaction(privateKey, receiveAddress, amountInWei, txCount.Value, gasPrice, gasLimit);
//This is what prompts the transactions
Web3.OfflineTransactionSigner.GetSenderAddress(encoded).Dump();
//TX Returns from this action
var txId = await web3.Eth.Transactions.SendRawTransaction.SendRequestAsync("0x" + encoded);
//Dump out the TX if successful
txId.Dump();
I've used this many times and it has worked for me just fine.

Part of my url get's removed upon adding a relative path

I have a base url http://some.com/url/that/does/something and a relative url this/is/a/specific/path.
Whenever I try to combine the two using new Uri(baseUrl, relativeUrl) some part of the base url gets cropped. The results with above example is
var baseUrl = new Uri("http://some.com/url/that/does/something")
var relativeUrl = "this/is/a/specific/path";
var Url = new Uri(baseUrl, relativeUrl);
// result is = http://some.com/url/that/does/this/is/a/specific/path
As you might have noticed the something disappeared.
How am I supposed to solve this?
I couldn't find any examples by Googling or searching here on Stackoverflow.com.
You were missing /
Here is Your Answer
var baseUrl = new Uri("http://some.com/url/that/does/something/");
var relativeUrl = "this/is/a/specific/path";
var Url = new Uri(baseUrl, relativeUrl);

How to set ImageResizer configuration programmatically?

I want to set the configuration parameter clientcache.minutesprogrammatically but im struggling with the config design in ImageResizer.
My approach currently is:
var lWebConfigReader = new System.Xml.XmlTextReader(#"Web.config");
var lXmlDocument = new System.Xml.XmlDocument();
lXmlDocument.Load(lWebConfigReader);
var lResizerNode = lXmlDocument.SelectSingleNode("/configuration/resizer");
var lSection = new ImageResizer.ResizerSection(lResizerNode.OuterXml);
var lConfig = new ImageResizer.Configuration.Config(lSection);
int mins = lConfig.get("clientcache.minutes", -1);
...
ImageResizer.Configuration.Config.Current.setConfigXml(lConfig.getConfigXml());
It seems a bit hacky and also doesn't work as the ClientCache plugin doesn't sent the Expires header as it normally should when clientcache.minutes is set.
What could be the issue?
After some digging in the source code i found out that in this particular case you need to alter the global configuration object as the ClientCache plugin reads the parameter via Get() from it. So my current solution is:
// read a XML where a <resizer>...</resizer> is present, in this case a typical Web.config as mentioned in the ImageResizer docs
var lWebConfigReader = new System.Xml.XmlTextReader(#"Web.config");
var lXmlDocument = new System.Xml.XmlDocument();
lXmlDocument.Load(lWebConfigReader);
// read the resizer tag to a node
var lResizerNode = lXmlDocument.SelectSingleNode("/configuration/resizer");
// create a section from the node
var lSection = new ImageResizer.ResizerSection(lResizerNode.OuterXml);
// create a new config object from the section
var lConfig = new ImageResizer.Configuration.Config(lSection);
// override the global configugration with the newly created one
ImageResizer.Configuration.Config.Current.setConfigXml(lConfig.getConfigXml());
// test the Get() call used by the ClientCache plugin
int mins = ImageResizer.Configuration.Config.Current.get("clientcache.minutes", -1);
This code could be placed in a ICurrentConfigProvider implementation or Application_Start() in Global.asax.

How does one connect to the RootDSE and/or retrieve highestCommittedUSN with System.DirectoryServices.Protocols?

Using System.DirectoryServices, one can get the highestCommittedUSN this way:
using(DirectoryEntry entry = new DirectoryEntry("LDAP://servername:636/RootDSE"))
{
var usn = entry.Properties["highestCommittedUSN"].Value;
}
However, I need to get this information from a remote ADLDS using System.DirectoryServices.Protocols, which does not leverage ADSI. Following is a simplified code sample of what I'm attempting to do:
using(LdapConnection connection = GetWin32LdapConnection())
{
var filter = "(&(highestCommittedUSN=*))";
var searchRequest = new SearchRequest("RootDSE", filter, SearchScope.Subtree, "highestCommittedUSN");
var response = connection.SendRequest(searchRequest) as SearchResponse;
var usn = response.Entries[0].Attributes["highestCommittedUSN"][0];
}
Unfortunately this kicks back a "DirectoryOperationException: The distinguished name contains invalid syntax." At first I thought there might be something wrong in GetWin32LdapConnection() but that code is called in numerous other places to connect to the directory and never errors out.
Any ideas?
Thanks for the idea, Zilog. Apparently to connect to the RootDSE, you have to specify null for the root container. I also switched the filter to objectClass=* and the search scope to "base." Now it works!
using(LdapConnection connection = GetWin32LdapConnection())
{
var filter = "(&(objectClass=*))";
var searchRequest = new SearchRequest(null, filter, SearchScope.Base, "highestCommittedUSN");
var response = connection.SendRequest(searchRequest) as SearchResponse;
var usn = response.Entries[0].Attributes["highestcommittedusn"][0];
}
I hope this saves someone else some time in the future.

How am I using the System.Uri incorrectly & MakeRelativeUri(..) method?

Update:
I added the missing two variables to the repo code blush Sincere appologies about that - I was rushing out to pick up the kids and missed it when i quickly reviewed the post.
When i call the .NET framework's MakeRelativeUri(...) method and the pass in a Uri which contains a file path .. and the file path has spaces in it .. then there's a great disturbance in the Force, as if millions of voices suddenly cried out in terror, and were suddenly silenced.
Here's my repo code. Appologies for this being an MSTest repo and not something a bit nicer like NUnit or XUnit.
[TestMethod]
public void SadPanda()
{
// Arrange.
var outputPath =
#"C:\Users\AAAAAAA.BBBBB\Documents\Visual Studio 2010\Projects\XWing\Code\CCCCCCCCCCC.XWing.Application.Web\content\shared\css\___sa.bundle.#.css";
var sourcePath =
#"C:\Users\AAAAAAA.BBBBB\Documents\Visual Studio 2010\Projects\XWing\Code\CCCCCCCCCCC.XWing.Application.Web\content\shared\css\home.css";
var sourcePathJussy =
#"C:\Projects\XWing\Code\CCCCCCCCCCC.XWing.Application.Web\content\shared\css\home.css";
// Added missing 2x vars *blush*
var sourceUri = new Uri(Path.GetDirectoryName(sourcePath) + "/", UriKind.Absolute);
var outputUri = new Uri(Path.GetDirectoryName(outputPath) + "/", UriKind.Absolute);
var relativePath = "../images/home-feature-bg.png";
var resolvedSourcePath = new Uri(sourceUri + relativePath, true);
// Act.
var resolvedOutput = outputUri.MakeRelativeUri(resolvedSourcePath);
// Assert.
Assert.IsTrue(resolvedOutput.Contains("XWing")); // :~(
}
Now if you look at the output it is something evil with the real path of the location, etc.
Now if we remove the SPACES from the paths, it now works :)
[TestMethod]
public void DoubleRaindbowUnicorns()
{
// Arrange.
var outputPath =
#"C:\Users\AAAAAAA.BBBBB\Documents\Visual Studio 2010\Projects\XWing\Code\CCCCCCCCCCC.XWing.Application.Web\content\shared\css\___sa.bundle.#.css";
var sourcePath =
#"C:\Users\AAAAAAA.BBBBB\Documents\Visual Studio 2010\Projects\XWing\Code\CCCCCCCCCCC.XWing.Application.Web\content\shared\css\home.css";
var sourcePathJussy =
#"C:\Projects\XWing\Code\CCCCCCCCCCC.XWing.Application.Web\content\shared\css\home.css";
outputPath = outputPath.Replace(" ", "-");
sourcePath = sourcePath.Replace(" ", "-");
// Added missing 2x vars *blush*
var sourceUri = new Uri(Path.GetDirectoryName(sourcePath) + "/", UriKind.Absolute);
var outputUri = new Uri(Path.GetDirectoryName(outputPath) + "/", UriKind.Absolute);
var relativePath = "../images/home-feature-bg.png";
var resolvedSourcePath = new Uri(sourceUri + relativePath, true);
// Act.
var resolvedOutput = outputUri.MakeRelativeUri(resolvedSourcePath);
// Assert.
Assert.IsFalse(resolvedOutput.Contains("XWing")); // Here yee! Woot, say I!
}
the output of this image resource is ../images/home-feature-bg.png (which by fluke is the same as it's source path) .. and not the really long evil string.
Yes / no ?
Update 2:
Renamed the subject (to better reflect the answer).
You need to use the System.IO.Path.Combine() function. What's happening here is you are using a URI class which cannot contain spaces, which would require the %20 if it were a path for HTML.
I think you are misunderstanding the purpose of the MakeRelativeUri() function. It is supposed to be called on one absolute URI taking in another in order to return the relative URI which represents how to arrive at the second resource in context of the first.
Example:
var cssFileUri = new Uri(#"C:\Temp\Spaces in this path\foo.css");
var imageFileUri = new Uri(#"C:\Temp\Images\bar.png");
var relativeUri = cssFileUri.MakeRelative(imageFileUri);
// The value of relativeUri is "../Images/bar.png"
So you can see how the relativeUri value gets us to the "bar.png" file from "foo.css".
In your example you'd pass in your CSS file path and a path to the image to get the value you have in relativePath.
In order to "undo" that (find the full path of an image in relation to a given CSS file) you construct a new Uri object:
var relativeImageUri = #"..\Image Folder\bar.png";
var cssFileUri = new Uri(#"C:\Some Path\Other Folder\foo.css");
var absoluteImageUri = new Uri(cssFileUri, relativeImageUri);
// The value of absoluteImageUri is "file:///C:/Some Path/Image Folder/bar.png"
So in order to find the resolvedOutput from your sample code:
var outputPath = #"C:\Users\AAAAAAA.BBBBB\Documents\Visual Studio 2010 Projects\XWing\Code\CCCCCCCCCCC.XWing.Application.Web\content\shared\css\___sa.bundle.#.css";
var sourcePath = #"C:\Users\AAAAAAA.BBBBB\Documents\Visual Studio 2010\Projects\XWing\Code\CCCCCCCCCCC.XWing.Application.Web\content\shared\css\home.css";
var relativePath = "../images/home-feature-bg.png";
var outputUriBase = new Uri(outputPath);
var resolvedOutput = new Uri(outputUriBase, relativePath);
You can now use the resolvedOutput Uri object to access the "home-feature-bg.png" image relative to the output path.
All these handle spaces in the path without error.
The
uriInstance.MakeRelativeUri()
method seems to be corrupt. The resulting Uri will show escaped characters when called with ToString(), e.g. %20 for an empty space. Other Uri instances don't do so, not even relative ones.
I wanted to use it for creating relative paths by subtracting the root path from a full path, then store a string from it in a DB
var baseUri = new Uri("http://myserver/pics")
var fullUri = new Uri("http://myserver/pics/myself/smile a.jpg")
var madeRelativeUri = baseUri.MakeRelativeUri(fullUri)
// madeRelativeUri.ToString() = "myself/smile%20a.jpg"
var manualRelativeUri = new Uri(#"myself/smile b", UriKind.Relative)
// manualRelativeUri.ToString() = "myself/smile b.jpg" // no escape

Categories