Currency Convertor Web Service - c#

I am trying to make use of a currency conversion web service in my website. I have added a reference to the .asmx file.
Here is my code:
net.webservicex.www.CurrencyConvertor Convertor; //creating instance of web service
float new_donation = donation * Convertor.ConversionRate("EUR", "GBP"); //converting donation to new value
The problem is that the second line I posted is giving me the following errors:
The best overloaded method match for 'abc.net.webservicex.www.CurrencyConvertor.ConversionRate(abc.net.webservicex.www.Currency, abc.net.webservicex.www.Currency)' has some invalid arguments
Argument 1: cannot convert from 'string' to 'abc.net.webservicex.www.Currency'
Argument 2: cannot convert from 'string' to 'abc.net.webservicex.www.Currency'
Here is the link to the web service description:
http://www.webservicex.net/ws/wsdetails.aspx?wsid=10
How can I solve this problem? Thank you in advance.

It's telling you clear as day... you're passing in 2 strings to you're ConversionRate(...) method when it is expecting 2 Currencys.
This seems like it might not be a WebService you are in control of, but just a consumer of...
First, the easiest way to handle consuming this WebService is to use the "Add Service Reference..." in your project (WSDL Address: http://www.webservicex.net/CurrencyConvertor.asmx?WSDL) ...
But, if you want to do it manually then create an enumeration to use and pass in an enumeration value...
public enum Currency
{
AFA,
ALL,
...
}
Convertor.ConversionRate(Currency.EUR, Currency.GBP);

Instead of use string "EUR" use Convertor.Currency.EUR.

I'm pretty new to C# and WPF so I went through the same phase as you did.
Let me try to give a step by step method to make it work.
As some of the other posts said already, first you will need to add the web reference. You can do this by going to your Solution Explorer, right click on "Service References", and click "Add Service Reference". In the new window, click "Advanced" at the bottom, and in the next window click "Add Web Reference" at the bottom. Then type URL:
"http://www.webservicex.net/CurrencyConvertor.asmx?WSDL"
Normally by now it should be looking for available services related to this URL, and find one: "CurrencyConverter". Give it a reference name such as "net.webservicex.www" and click "Add Reference". Now you can use it in your code.
Let's go to the code now. If you would like to display, for example, the Euro / US Dollar exchange rate, all you need is this code:
net.webservicex.www.CurrencyConvertor conver = new net.webservicex.www.CurrencyConvertor();
MessageBox.Show((conver.ConversionRate(net.webservicex.www.Currency.EUR, net.webservicex.www.Currency.USD)).ToString());
conver.dispose();
Hope this helps!

I wrote this a while back, I call the current currencies and store them in the class as the json object. This makes calculations across multiple currencies faster as you are doing on the platform.
getCurrencies -> returns string[] "EUR","USD" etc
calculate -> ("USD","EUR",1.0) converts 1 dollar into euros
class CurrencyConvertor
{
public string[] currencyList;
RestClient client = new RestClient ("http://finance.yahoo.com/webservice/v1/symbols/allcurrencies/quote?format=json");
RestRequest request = new RestRequest ("",Method.GET);
JObject json;
public CurrencyConvertor()
{
var response = client.Execute(request);
json = JObject.Parse (response.Content);
}
public string[] getCurrencies()
{
ArrayList currencies = new ArrayList ();
foreach (var item in json["list"]["resources"]) {
string tempN = item ["resource"] ["fields"] ["name"].ToString ().Replace ("USD/", "");
if(tempN.Length < 4)
currencies.Add (tempN);
}
currencies.Sort ();
currencyList = (string[])currencies.ToArray(typeof(string));
return currencyList;
}
public string calculate(string Base, string Target, decimal amount)
{
decimal temp1 = 1;
decimal temp2 = 1;
Console.WriteLine (Base + "to"+Target);
foreach (var item in json["list"]["resources"]) {
if (item["resource"]["fields"]["name"].ToString().Contains("/"+Base)) {
temp1 = decimal.Parse(amount.ToString()) * decimal.Parse(item ["resource"] ["fields"] ["price"].ToString(), CultureInfo.InvariantCulture.NumberFormat);
}
if (item ["resource"] ["fields"] ["name"].ToString().Contains("/"+Target)) {
temp2=decimal.Parse(amount.ToString()) * decimal.Parse(item ["resource"] ["fields"] ["price"].ToString(), CultureInfo.InvariantCulture.NumberFormat);
}
}
var dec = ((decimal)temp2 / (decimal)temp1);
return (Math.Round(dec*amount,5) ).ToString().Replace(",",".");
}
}

Related

nhapi - Modifiy a segment value

Env :
Visual Studio 2013,
Winform / C# / Framework 4.5,
nHapi DLL 2.4.0.9,
HL7 Version 2.3
I'm building a little windows application that read HL7 messages and send them to an Interface system.
Everything is working just fine but I would like to know if it's possible to replace/add/modify a segment value : EVN 5.2 (Operator ID / Family name).
At the moment, I'm reading the content of the HL7 file on the computer, put the content in a string, parse the message, encode the message and return it.
public static String ParseMessage(String message)
{
var parser = new NHapi.Base.Parser.PipeParser();
var parsedMessage = parser.Parse(message);
/* I guess it's here that I should do the change for the EVN 5.2 ? But How ;-) */
var msgType = parsedMessage.GetStructureName();
var pipeDelimitedMessage = parser.Encode(parsedMessage);
return pipeDelimitedMessage;
}
Thanks everyone for you help
Richard
The way the nHapi would have you do this is cast the 'parsed' abstract message down to its concrete type so that you are able to walk the object model and set the properties you'd like.
As an example, take the case of an ADT A01 admit message:
[Test]
public void TestPopulateEVNOperaterID()
{
string message = #"MSH|^~\&|SUNS1|OVI02|AZIS|CMD|200606221348||ADT^A01|1049691900|P|2.3
EVN|A01|200601060800
PID||8912716038^^^51276|0216128^^^51276||BARDOUN^LEA SACHA||19981201|F|||AVENUE FRANC GOLD 8^^LUXEMBOURGH^^6780^150||053/12456789||N|S|||99120162652||^^^|||||B
PV1||O|^^|U|||07632^MORTELO^POL^^^DR.|^^^^^|||||N||||||0200001198
PV2|||^^AZIS||N|||200601060800
IN1|0001|2|314000|||||||||19800101|||1|BARDOUN^LEA SACHA|1|19981201|AVENUE FRANC GOLD 8^^LUXEMBOURGH^^6780^150|||||||||||||||||ZIN|0164652011399|0164652011399|101|101|45789^Broken bone";
var parser = new PipeParser();
var abstractMessage = parser.Parse(message);
// this is the normal / expected way of working with NHapi parsed messages
var typedMessage = abstractMessage as ADT_A01;
if (typedMessage != null)
{
typedMessage.EVN.OperatorID.FamilyName.Value = "Surname";
typedMessage.EVN.OperatorID.GivenName.Value = "Firstname";
}
var pipeDelimitedMessage = parser.Encode(typedMessage);
// alternatively, you can apply this modification to any HL7 2.3 message
// with an EVN segment using this more generic method
var genericMethod = abstractMessage as AbstractMessage;
var evn = genericMethod.GetStructure("EVN") as EVN;
if (evn != null)
{
evn.OperatorID.FamilyName.Value = "SurnameGeneric";
evn.OperatorID.GivenName.Value = "FirstnameGeneric";
}
pipeDelimitedMessage = parser.Encode(typedMessage);
}
I believe the second more generic way is probably what you'll be wanting for this case, however I thought I'd just show you as well how to get to parsed / concrete type so that you can work with it that way if you are dealing with a specific message type.

Get specific subdomain from URL in foo.bar.car.com

Given a URL as follows:
foo.bar.car.com.au
I need to extract foo.bar.
I came across the following code :
private static string GetSubDomain(Uri url)
{
if (url.HostNameType == UriHostNameType.Dns)
{
string host = url.Host;
if (host.Split('.').Length > 2)
{
int lastIndex = host.LastIndexOf(".");
int index = host.LastIndexOf(".", lastIndex - 1);
return host.Substring(0, index);
}
}
return null;
}
This gives me like foo.bar.car. I want foo.bar. Should i just use split and take 0 and 1?
But then there is possible wwww.
Is there an easy way for this?
Given your requirement (you want the 1st two levels, not including 'www.') I'd approach it something like this:
private static string GetSubDomain(Uri url)
{
if (url.HostNameType == UriHostNameType.Dns)
{
string host = url.Host;
var nodes = host.Split('.');
int startNode = 0;
if(nodes[0] == "www") startNode = 1;
return string.Format("{0}.{1}", nodes[startNode], nodes[startNode + 1]);
}
return null;
}
I faced a similar problem and, based on the preceding answers, wrote this extension method. Most importantly, it takes a parameter that defines the "root" domain, i.e. whatever the consumer of the method considers to be the root. In the OP's case, the call would be
Uri uri = "foo.bar.car.com.au";
uri.DnsSafeHost.GetSubdomain("car.com.au"); // returns foo.bar
uri.DnsSafeHost.GetSubdomain(); // returns foo.bar.car
Here's the extension method:
/// <summary>Gets the subdomain portion of a url, given a known "root" domain</summary>
public static string GetSubdomain(this string url, string domain = null)
{
var subdomain = url;
if(subdomain != null)
{
if(domain == null)
{
// Since we were not provided with a known domain, assume that second-to-last period divides the subdomain from the domain.
var nodes = url.Split('.');
var lastNodeIndex = nodes.Length - 1;
if(lastNodeIndex > 0)
domain = nodes[lastNodeIndex-1] + "." + nodes[lastNodeIndex];
}
// Verify that what we think is the domain is truly the ending of the hostname... otherwise we're hooped.
if (!subdomain.EndsWith(domain))
throw new ArgumentException("Site was not loaded from the expected domain");
// Quash the domain portion, which should leave us with the subdomain and a trailing dot IF there is a subdomain.
subdomain = subdomain.Replace(domain, "");
// Check if we have anything left. If we don't, there was no subdomain, the request was directly to the root domain:
if (string.IsNullOrWhiteSpace(subdomain))
return null;
// Quash any trailing periods
subdomain = subdomain.TrimEnd(new[] {'.'});
}
return subdomain;
}
You can use the following nuget package Nager.PublicSuffix. It uses the PUBLIC SUFFIX LIST from Mozilla to split the domain.
PM> Install-Package Nager.PublicSuffix
Example
var domainParser = new DomainParser();
var data = await domainParser.LoadDataAsync();
var tldRules = domainParser.ParseRules(data);
domainParser.AddRules(tldRules);
var domainName = domainParser.Get("sub.test.co.uk");
//domainName.Domain = "test";
//domainName.Hostname = "sub.test.co.uk";
//domainName.RegistrableDomain = "test.co.uk";
//domainName.SubDomain = "sub";
//domainName.TLD = "co.uk";
private static string GetSubDomain(Uri url)
{
if (url.HostNameType == UriHostNameType.Dns)
{
string host = url.Host;
String[] subDomains = host.Split('.');
return subDomains[0] + "." + subDomains[1];
}
return null;
}
OK, first. Are you specifically looking in 'com.au', or are these general Internet domain names? Because if it's the latter, there is simply no automatic way to determine how much of the domain is a "site" or "zone" or whatever and how much is an individual "host" or other record within that zone.
If you need to be able to figure that out from an arbitrary domain name, you will want to grab the list of TLDs from the Mozilla Public Suffix project (http://publicsuffix.org) and use their algorithm to find the TLD in your domain name. Then you can assume that the portion you want ends with the last label immediately before the TLD.
I would recommend using Regular Expression. The following code snippet should extract what you are looking for...
string input = "foo.bar.car.com.au";
var match = Regex.Match(input, #"^\w*\.\w*\.\w*");
var output = match.Value;
In addition to the NuGet Nager.PubilcSuffix package specified in this answer, there is also the NuGet Louw.PublicSuffix package, which according to its GitHub project page is a .Net Core Library that parses Public Suffix, and is based on the Nager.PublicSuffix project, with the following changes:
Ported to .NET Core Library.
Fixed library so it passes ALL the comprehensive tests.
Refactored classes to split functionality into smaller focused classes.
Made classes immutable. Thus DomainParser can be used as singleton and is thread safe.
Added WebTldRuleProvider and FileTldRuleProvider.
Added functionality to know if Rule was a ICANN or Private domain rule.
Use async programming model
The page also states that many of above changes were submitted back to original Nager.PublicSuffix project.

Extracting a key-value pair from a web service XML response

I'm working with C# and the .NET 2.0 framework in Visual Studio 2010.
I'm trying to extract a URL which is returned by a web service.
This URL is returned in an array of features containing keys and values. (I think this is similar to what I learned in school is called a hash table).
My intellisense doesn't pick up anything useful and I can't figure out what I'm doing wrong.
This is the code. What goes in serverInfo.FeatureSet[]?
public string wfl_reqURL(string username, string password)
{
MyWorkflow.ServerInfo serverInfo = new MyWorkflow.ServerInfo();
myURL = serverInfo.FeatureSet[];
}
This is how it's described in the WSDL. FeatureSet is being returned as an array with a string key and a string value:
<ServerInfo>
<FeatureSet>
<Feature>
<Key>FileUploadUrl</Key>
<Value>http://localhost/transferindex.php</Value>
</Feature>
</FeatureSet>
</ServerInfo>
Have I provided enough detail about my problem? Most of the information I've found seems to be about how to create such arrays in web services, not select one from a web service as I'd like to do.
Try something like this:
object neededItem = null;
foreach (string item in serverInfo.FeatureSet.Keys)
{
if (item == "FileUploadUrl")
{
neededItem = serverInfo.FeatureSet[item];
break;
}
}
if (neededItem != null)
{
//Do something
}
If you're using c# 3.5 then something in linq like
myURL = serverInfo.FeatureSet.First(o=>o.Key == "FileUploadUrl").Value
The problem was in the data type. Changing the code to this solved the problem, albeit in a messy way. I thought it had something to do with types and how it was defined...either as dictionary or arrays, but it was a bit different than I'd thought...
foreach( MyWorkFlow.Feature feature in serverInfo.FeatureSet) {
if (feature.Key.ToString() == "FileUploadUrl") {
string myURL = feature.Value;
Console.WriteLine(myURL);
}

How do you use the CopyIntoItems method of the SharePoint Copy web service?

I am attempting to load document files into a document library in SharePoint using the CopyIntoItems method of the SharePoint Copy web service.
The code below executes and returns 0 (success). Also, the CopyResult[] array returns 1 value with a "Success" result. However, I cannot find the document anywhere in the library.
I have two questions:
Can anyone see anything wrong with my code or suggest changes?
Can anyone suggest how I could debug this on the server side. I don't have a tremendous amount of experience with SharePoint. If I can track what is going on through logging or some other method on the server side it may help me figure out what is going on.
Code Sample:
string[] destinationUrls = { Uri.EscapeDataString("https://someaddress.com/Reports/Temp") };
SPCopyWebService.FieldInformation i1 = new SPCopyWebService.FieldInformation { DisplayName = "Name", InternalName = "Name", Type = SPListTransferSpike1.SPCopyWebService.FieldType.Text, Value = "Test1Name" };
SPCopyWebService.FieldInformation i2 = new SPCopyWebService.FieldInformation { DisplayName = "Title", InternalName = "Title", Type = SPListTransferSpike1.SPCopyWebService.FieldType.Text, Value = "Test1Title" };
SPCopyWebService.FieldInformation[] info = { i1, i2 };
SPCopyWebService.CopyResult[] result;
byte[] data = File.ReadAllBytes("C:\\SomePath\\Test1Data.txt");
uint ret = SPCopyNew.CopyIntoItems("", destinationUrls, info, data, out result);
Edit that got things working:
I got my code working by adding "http://null" to the SourceUrl field. Nat's answer below would probably work for that reason. Here is the line I changed to get it working.
// Change
uint ret = SPCopyNew.CopyIntoItems("http://null", destinationUrls, info, data, out result);
I think the issue may be in trying to set the "Name" property using the webservice. I have had some fail doing that.
Given the "Name" is the name of the document, you may have some success with
string targetDocName = "Test1Name.txt";
string destinationUrl = Uri.EscapeDataString("https://someaddress.com/Reports/Temp/" + targetDocName);
string[] destinationUrls = { destinationUrl };
SPCopyWebService.FieldInformation i1 = new SPCopyWebService.FieldInformation { DisplayName = "Title", InternalName = "Title", Type = SPListTransferSpike1.SPCopyWebService.FieldType.Text, Value = "Test1Title" };
SPCopyWebService.FieldInformation[] info = { i1};
SPCopyWebService.CopyResult[] result;
byte[] data = File.ReadAllBytes("C:\\SomePath\\Test1Data.txt");
uint ret = SPCopyNew.CopyIntoItems(destinationUrl, destinationUrls, info, data, out result);
Note: I have used the "target" as the "source" property. Don't quite know why, but it does the trick.
I didn't understand very well what you're tying to do, but if you're trying to upload a file from a local directory into a sharepoint library, i would suggest you create a webclient and use uploadata:
Example (VB.NET):
dim webclient as Webclient
webClient.UploadData("http://srvasddress/library/filenameexample.doc", "PUT", filebytes)
Then you just have to check in the file using the lists web service, something like:
listService.CheckInFile("http://srvasddress/library/filenameexample.doc", "description", "1")
Hope it was of some help.
EDIT: Don't forget to set credentials for the web client, etc.
EDIT 2: Update metada fields using this:
listService.UpdateListItems("Name of the Library, batchquery)
You can find info on building batch query's in here: link
The sourceurl is used in Sharepoint. It is a link back to the "Source Document." When in your document library, hover over the item, to the right appears a down pointing triangle. Clicking on it, brings up a menu. Click on the "View Properties" Option. On this page you will see the following "This item is a copy of http://null ( Go To Source Item | Unlink )"
Because we are using the Copy function Sharepoint is keeping track of the "Source item" as part of the Document Management feature.

Cannot Convert from 'List<T>' to 'T[]'

I am trying to pass a list object of type List<UploadQueue> to a WCF SOAP
method of the same parameter type and I am getting the error:
Cannot Convert from
'System.Collections.Generic.List'
to 'WebAPI.Upload.UploadQueue[]'
I don't understand this because my WCF method's (below) parameter type is List<UploadQueue>:
IService.DoUpload(List<UploadQueue> request)
Here is the code that calls "DoUpload" which returns the above error.
List<UploadQueue> results = new List<UploadQueue>();
HttpPostedFile m_objFile = default(HttpPostedFile);
int m_objFlag = default(int);
Guid m_objGuid = Guid.NewGuid();
DateTime m_objDate = DateTime.Now;
try
{
if (Request.Files.Count > 0)
{
for (var j = 0; i <= (Request.Files.Count - 1); j++)
{
m_objFile = Request.Files[j];
if (!(m_objFile == null | string.IsNullOrEmpty(m_objFile.FileName) | m_objFile.ContentLength < 1))
{
results.Add(new UploadQueue(
m_objGuid,
m_objFlag,
m_objFile.ContentLength,
m_objFile.FileName,
m_objDate)
);
}
}
}
}
catch (Exception ex)
{
//handle error
}
retParam = upload.DoUpload(results);
Ideas? Thanks.
In your client project, you need to right click on the service reference and select "Configure Service Reference". On configuration screen, in the Data Type section, you need to set the collection type to System.Collections.Generic.List instead of System.Array.
The generated client has replaced the List with an Array (The default behaviour). With VS.NET 2008 you have the option of generating this with a List instead- look at the Configure Service Dialog Box. As other have said ToArray will work.
Try doing results.ToArray(). That will probably fix it.
upload.DoUpload(results.ToArray());
The problem is that the soap service says that it wants an array of objects, and not a list. When the proxy class is built from the WSDL, it converts it to the most basic object it can that satisfies the needs of the service which is an array.
retParam = upload.DoUpload(results.ToArray());
...or similar.

Categories

Resources