|
Hello there!
I have a third party web service that was written in PHP. I've added the web reference to visual studio and the methods take an object[] as the parameter.
Now according to their documentation if I were to create this client in php it would look something like this for the object[]:
$params = array(
‘username’ => $user,
‘password’ => $pass,
‘param1’ => $param1_value,
);
How do I create this in C#? I can't do Dictionary<string, string=""> because I can't convert that to an object[].
|
|
|
|
|
|
I tried your suggestions:
Custom Class:
class MCInfo
{
public string username { get; set; }
public string password { get; set; }
public string supportname { get; set; }
}
Linq:
List<MCInfo> info = new List<MCInfo>();
info.Add(
new MCInfo()
{
username = "administrator",
password = "testing",
supportname = "BLAH BLAH"
});
var results = (from n in info
select new
{
username = n.username,
password = n.password,
supportname = n.supportname
}).ToArray();
Invoke:
object[] blah = soap.domainEdit("blah.com", results);
Unfortunately it doesn't look like the other end is able to process it:
System.InvalidOperationException: There was an error generating the XML document
. ---> System.InvalidOperationException: <>f__AnonymousType0`3[System.String,Sys
tem.String,System.String] cannot be serialized because it does not have a parame
terless constructor.
at System.Xml.Serialization.TypeDesc.CheckSupported()
at System.Xml.Serialization.TypeScope.GetTypeDesc(Type type, MemberInfo sourc
e, Boolean directReference, Boolean throwOnError)
at System.Xml.Serialization.XmlSerializationWriter.CreateUnknownTypeException
(Type type)
at System.Xml.Serialization.XmlSerializationWriter.GetPrimitiveTypeName(Type
type, Boolean throwIfUnknown)
at System.Xml.Serialization.XmlSerializationWriter.WriteArray(String name, St
ring ns, Object o, Type type)
at System.Xml.Serialization.XmlSerializationWriter.WriteReferencedElement(Str
ing name, String ns, Object o, Type ambientType)
at System.Xml.Serialization.XmlSerializationWriter.WriteReferencedElements()
at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterApi_Mo
del_SoapInterfaceService.Write31_domainEdit(Object[] p)
at Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer61.Se
rialize(Object objectToSerialize, XmlSerializationWriter writer)
at System.Xml.Serialization.XmlSerializer.Serialize(XmlWriter xmlWriter, Obje
ct o, XmlSerializerNamespaces namespaces, String encodingStyle, String id)
--- End of inner exception stack trace ---
at System.Xml.Serialization.XmlSerializer.Serialize(XmlWriter xmlWriter, Obje
ct o, XmlSerializerNamespaces namespaces, String encodingStyle, String id)
at System.Xml.Serialization.XmlSerializer.Serialize(XmlWriter xmlWriter, Obje
ct o, XmlSerializerNamespaces namespaces, String encodingStyle)
at System.Web.Services.Protocols.SoapHttpClientProtocol.Serialize(SoapClientM
essage message)
at System.Web.Services.Protocols.SoapHttpClientProtocol.Invoke(String methodN
ame, Object[] parameters)
at **********.com.domain.mta1_ar1.Api_Model_SoapInterfaceService.d
omainEdit(String domain_name, Object[] params) in C:\Users\*****\Dropbox\C
ompsys\****\*****t\Web References\com.*****.mta1-ar1\
Reference.cs:line 226
at *****.Program.Main(String[] args) in C:\Users\*******\Dropbo
x\*****\******\******\Program.cs:line 107
I haven't worked with XML or soap calls much.
|
|
|
|
|
That absolutely is a dictionary. I'm surprised a dictionary doesn't generate the correct service XML ... have you tried passing the dictionary as the only argument to the service method?
|
|
|
|
|
The problem with that is the only parameter it wants is an object array (object[]).
So how do I convert a dictionary into an object[]? They are completely different types of arrays.
These methods were generated when I added the service to visual studio. Maybe I should try calling the service manually?
|
|
|
|
|
You can try new object[]{ dict } which will create a one element array for parameters.
I don't really trust VS's automagical code generation but you can check the WSDL that the service exposes to see what the SOAP type of the parameter it expects is, and then try searching for that plus C# to see what .Net type will resolve to that.
|
|
|
|
|
I'll try to find that information. Browsing to the wsdl service this is what I see:
<message name="domainEditIn">
<part name="domain_name" type="xsd:string"/>
<part name="params" type="soap-enc:Array"/>
</message>
|
|
|
|
|
Hm, so that is just an array. Do you have a working PHP client? Try request-spying what it sends to the service and see what it's sending there. I had a very quick search and I didn't find a page explaining how PHP maps an associative array to a soap-enc:Array.
|
|
|
|
|
I don't have a working PHP client.
The API is here: http://www.mailcleaner.net/downloads/MailCleanerAPI.pdf[^]
They gave an example of this to call with PHP:
$client = new SoapClient(‘https:
$params = array(
‘spam_tag’ => ‘{This is a spam}’,
‘summary_frequency’ => ‘weekly,
…
);
$result = $client->domainEdit(‘domain_name’, $params);
if ($result[‘code’] == 200) {
echo ‘domain edited’ ;
}
So you can see that PHP is doing a multidimensional array.. but there isn't a way to create this array with C# and convert it to object[].
I haven't done it before but maybe calling the soap manually instead of using the web reference?
|
|
|
|
|
I did some cleanup in my code, and now I'm getting the above error message, but I'm having trouble seeing the reason. I searched the internet and found this article, but I don't see that I'm having that issue.
http://www.softwareandfinance.com/forums/index.php?topic=314.0[^]
In my Program.cs class, I have the following lines of code.
Control control = new Control();
Assembly _assembly = Assembly.LoadFrom(programDll);
Type _type = _assembly.GetType("CWriter.ProgramControl");
Object _objectInstance = Activator.CreateInstance(_type);
I tried adding a breakpoint in the ProgramControl constructor, but it doesn't get hit. The constructor doesn't have any arguments to it.
|
|
|
|
|
Wrap the Activator.CreateInstance in a try/catch block and then take a look at the full exception. Is there an InnerException that provides more details (there should be)?
|
|
|
|
|
That helped a lot. Thanks! It looks like it can't find a file that the class it's trying to invoke is trying to use. I had pulled some code into it's own SerialNumber class. That's the problem. Thank you!
|
|
|
|
|
Hello again! Another problem needs to be solved, when users click button1 it creates new row in table with text from textbox1. I need it before adding created row to table to check if record already exists in column "iestade_nosaukums". Here is button1 code for adding new row.
private void button1_Click(object sender, EventArgs e)
{
datori_database.iestadesRow newiestadesRow;
newiestadesRow = datori_database.iestades.NewiestadesRow();
newiestadesRow.iestade_nosaukums = textBox1.Text;
this.datori_database.iestades.Rows.Add(newiestadesRow);
this.iestadesTableAdapter.Update(this.datori_database.iestades);
this.Validate();
this.iestadesBindingSource.EndEdit();
this.tableAdapterManager.UpdateAll(this.datori_database);
}
|
|
|
|
|
In the time between "checking" and "doing your thing", changes could occur. It's no fun to hunt for race-conditions in code.
The best way is to skip that check altogether, and deal with an exception if it occurs.
Bastard Programmer from Hell
|
|
|
|
|
yeah, you are right, it is easier this way, everything works now as it should. Thanks!
|
|
|
|
|
Rather than determining whether or not the record already exists, I would tend to use the following SQL:
INSERT INTO MyTable(SomeColumn)
SELECT @MyData
WHERE NOT EXISTS (SELECT SomeColumn FROM MyTable WHERE SomeColumn = @MyData) If you do a simple check, and then you do an insert and you are running this in a multi-user environment, you run the risk of adding a duplicate simply because you have two users doing the same checks at the same time.
As an alternative, put a unique constraint on the value you are trying to keep unique, and then just trap the resulting exception (this is not an ideal solution, but it is pretty much foolproof).
|
|
|
|
|
Thanks. I will try it later
|
|
|
|
|
Hello. So i have a filter that filters rows in datagridview:
private void button3_Click(object sender, EventArgs e)
{
iestadesBindingSource.Filter = string.Format("iestade_nosaukums like '%{0}%'", textBox1.Text.Trim().Replace("'", "''"));
}
When it doesn't find any records with criteria from textBox1.Text i need it to make visible label1.
|
|
|
|
|
Saidrex wrote: When it doesn't find any records with criteria from textBox1.Text i need it to make visible label1.
Where's the question? Simply check if your bindingsource contains records, and if it doesn't, hide the label.
Bastard Programmer from Hell
|
|
|
|
|
How to check if bindingsource contains records?
|
|
|
|
|
The bindingsource will not contain records directly; you would have assigned a datasource previously. Probably a list or a datatable
Bastard Programmer from Hell
|
|
|
|
|
it contains records from my datasource which contains tables from my database. I need it to check if there is any results after filtering. Any ideas how to do it? =)
|
|
|
|
|
Saidrex wrote: Any ideas how to do it? =)
Try MSDN[^].
"The Count property gets the number of items in the underlying list represented by the List property as modified by the value of the Filter property."
Bastard Programmer from Hell
|
|
|
|
|
yay, thanks, it works, my code:
private void button3_Click(object sender, EventArgs e)
{
iestadesBindingSource.Filter = string.Format("iestade_nosaukums like '%{0}%'", textBox1.Text.Trim().Replace("'", "''"));
int a = iestadesBindingSource.Count;
if ( a == 0)
{
label1.Text = "Error. No records with this keyword.";
}
}
|
|
|
|
|
Hi All,
We develop a windows application that can deal with sql server database directly or by Web Service,
We Want to add a new dialog to our setup wizard that configure the previous settings.
2 Radio buttons-> web service, directly
2 Text Boxes-> one for Web Service Url and the other for direct sql Connection.
Please help me if you know how to do that.
Thanks All.
|
|
|
|