3

i need to make a ("webservice") c# app that can create/update/delete nodes for/from drupal 7 using xmlrpc. everytime i run my app i get errors from the xmlrpc files(library). I tried to find code/documentation for C# using xmlrpc to connect to drupal, but in vain. I would be nice if you could point me in the right direction, or share some c# code with me.

{
[XmlRpcUrl("http://testing/testserver")]
public interface IDrupalServices
{
    [XmlRpcMethod("node.get")]
    XmlRpcStruct NodeLoad(int nid, string[] field);
    [XmlRpcMethod("node.save")]
    void NodeSave(XmlRpcStruct node);
}

public partial class Form1 : Form
{

    public Form1()
    {
        InitializeComponent();

        IDrupalServices drupal = XmlRpcProxyGen.Create<IDrupalServices>();

        int nid = 227;
        string[] fields = new string[] { };

        XmlRpcStruct node = drupal.NodeLoad(nid, fields);

        string teaser = node["teaser"].ToString();
        welcomeTxt.Text = teaser;
    }

    private void button1_Click(object sender, EventArgs e)
    {
        string title = txtTitle.Text;
        string body = txtBody.Text;

        IDrupalServices drupal = XmlRpcProxyGen.Create<IDrupalServices>();

        XmlRpcStruct node = new XmlRpcStruct();

        node["id"] = 1001;
        node["title"] = title;
        node["body"] = body;
        node["teaser"] = body;
        node["format"] = 1;
        node["type"] = "webservice";
        node["promote"] = false;

        drupal.NodeSave(node);
        MessageBox.Show("The post was been created!");

    }
}
}

After i run this i get the error: Server returned a fault exception: [-32601] Server error. Requested method node.get not specified. - in the XmlRpcSerializer.cs

Thank you, Florin

Sergiu
  • 53
  • 5
  • Please post sample code you've tried, and the actual error message you get. Check out http://tinyurl.com/so-hints – Mike Atlas Jan 14 '12 at 21:35

2 Answers2

3

If you're using Drupal 7 you must be using Services 3 which doesn't have a node.get method (or node.save as it happens). They've been replaced with node.retrieve and node.create & node.update respectively.

You can view all of the available methods in the resources/node_resource.inc file in the Services module folder.

UPDATE

Internally the node is submitted using drupal_execute which is the function used to submit a form. Since the body is a field in Drupal it's expected to be a multi-dimensional array in this format (PHP version):

$data["body"][$language][0]["value"]

The $language will either be the specific language for the node, or und for undefined language (unless you're dealing with a multi-lingual site und is usually the way to go). You'd need to build an array similar to that in your C# code and Drupal should save it.

ANOTHER UPDATE

The Java XML-RPC client example for Services uses a HashMap type to do this so my best guess is you could use a Dictionary (albeit one that seems unnecessarily complicated):

var innerValue = new Dictionary<string, string>();
innerValue.Add("value", txtBody.Text);

var language = new Dictionary<int, Dictionary<string, string>>();
language.Add(0, innerValue);

var body = new Dictionary<string, Dictionary<int, Dictionary<string, string>>>();
body.Add("und", language);

node["body"] = body;

It's been a few years since I've coded in C# so forgive any errors in there. Also I'm pretty sure it could be declared more efficiently but I've forgotten most of the language to be honest!

Clive
  • 36,918
  • 8
  • 87
  • 113
  • thank you, that worked.. but still i have a problem with the body of the node, if i add text to the node["body"] it won't appear. Can u tell me why? – Sergiu Jan 15 '12 at 10:37
  • @pretender: It's to do with the way Drupal expects fields on a node to be formatted (the body being a field in Drupal 7). I've updated the answer, hope it helps – Clive Jan 15 '12 at 13:40
  • i made an array [,,] but in vain. Could you share some code, if it's not too much to ask. i'll owe you one. thanks! – Sergiu Jan 15 '12 at 19:12
  • @pretender: I've had another go :) – Clive Jan 15 '12 at 19:44
  • thanks for the code:D the app runs but when i hit the button to create the node it gives and error in the XmlRpcStruct.cs --- System.Collections.Generic.Dictionary`2[System.String,System.Collections.Generic.Dictionary`2[System.Int32,System.Collections.Generic.Dictionary`2[System.String,System.String]]] cannot be mapped to an XML-RPC type – Sergiu Jan 15 '12 at 20:05
  • Thank you very much!!!! i managed to make it. Instead of dictionary i used XmlRpcStruct. works like a charm – Sergiu Jan 15 '12 at 20:16
  • Good stuff glad you got it sorted – Clive Jan 15 '12 at 21:21
  • Clive can u tell me how can i retrieve body from a specific node? thx! – Sergiu Jan 24 '12 at 09:58
0

Jan's answer is not quite right. If you are using the cook xmlrpc library all you would need to do is this:

        XmlRpcStruct postStruct = new XmlRpcStruct();
        postStruct.Add("type", "article");
        postStruct.Add("title", "wohoo another test");

        XmlRpcStruct postBodyStructParams = new XmlRpcStruct();
        postBodyStructParams.Add("value", "My body yaaay");
        postBodyStructParams.Add("format", "filtered_html");

        XmlRpcStruct[] postBodyStructParamsArr = new XmlRpcStruct[1];
        postBodyStructParamsArr[0] = postBodyStructParams;

        XmlRpcStruct postBodyStruct = new XmlRpcStruct();
        postBodyStruct.Add("und", postBodyStructParamsArr);

        postStruct.Add("body", postBodyStruct);

Unfortunately, the body params need to be an array of struct under the "und" key with only one value. I blame this on the sloppiness of the drupal xmlrpc API.

durron597
  • 31,968
  • 17
  • 99
  • 158
Eli Dadia
  • 11
  • 2