Artikel Export an Shopware mit vb.net

Ich versuche über REST API einen Artikel mit vb.net an den Shop zu übertragen, leider bisher nicht mit erfolg gekrönt. Hier mal mein Code: sUri = “http://**************.de.shopware-hosting.com/api/articles” Dim Request As HttpWebRequest = CType(WebRequest.Create(sUri), HttpWebRequest) Request.UseDefaultCredentials = False Request.Credentials = New NetworkCredential(Me.ApiUser, Me.ApiSchluessel) CType(Request, HttpWebRequest).UserAgent = “.NET Framework Example Client” Select Case nMethodeType Case APIMethode.HttpGet Request.Method = “GET” Case APIMethode.HttpPost Request.Method = “POST” 'Fatal error: Call to a member function getNumber() on a non-object in /bd1f98e8198c1c609e34ab73a16373d4/www/engine/Shopware/Components/Api/Resource/Article.php on line 618" Und der Artikel wurde natürlich auch nicht angelegt.

gugst Du hier: Imports System.Globalization Imports System.Net Imports Newtonsoft.Json Imports RestSharp Namespace ShopwareRestApiTest01 Friend Class Program Private Shared Sub Main() Const user As String = "API\_USER" Const pass As String = "DEIN\_API\_KEY" Dim client = New RestClient("http://www.shopwaredemo.de/api") With { \_ Key .Authenticator = New DigestAuthenticator(user, pass) \_ } Dim request = New RestRequest("articles/{id}", Method.[GET]) request.AddUrlSegment("id", 3.ToString(CultureInfo.InvariantCulture)) request.AddHeader("Content-Type", "application/json; charset=utf-8") Dim response = client.Execute(request) If response.ErrorException IsNot Nothing Then Console.WriteLine("################ ERROR ################") Console.WriteLine(response.ErrorException.Message) Else Dim content = response.Content Dim json As dynamic = JsonConvert.DeserializeObject(content) Console.WriteLine(json) End If End Sub End Class Public Class DigestAuthenticator Implements IAuthenticator Private ReadOnly \_user As String Private ReadOnly \_pass As String Public Sub New(user As String, pass As String) \_user = user \_pass = pass End Sub Public Sub Authenticate(client As IRestClient, request As IRestRequest) request.Credentials = New NetworkCredential(\_user, \_pass) End Sub End Class End Namespace

1 „Gefällt mir“

hey danke dir! Es gibt ja doch Leute hier die mit .NET unterwegs sind :smiley: sooo, aber was ist RestSharp, noch nie gehört!? Welchen Verweis muss ich da setzen, bzw wo bekomm ich das her? Und hast du noch ein Beispiel wie ein Artikel angelegt wird? In deinem Beispiel wird ein Artikel abgerufen, aber das ist leider nicht mein Problem. Artikel abzurufen ist kein Problem.

Google ist dein Freund :stuck_out_tongue: Erster Treffer: http://restsharp.org/ Anstatt abrufen GET einfach anlegen POST oder zum Updaten PUT schicken entsprechend dann in den Request.Body dein JSON stecken request.AddParameter("name", "value"); // adds to POST or URL querystring based on Method so ähnlich dann nur nicht dass es ein Parameter ist sondern eben der Body an sich

tja… ich weiss nicht, wie sieht es lizenztechnisch bei Restsharp aus? Im Grunde sollte es doch aber auch mit einem Httpwebrequest wie in meinem Beispiel funktionieren… Ich bin mir halt nicht sicher obs an meinem JSON String selber liegt. Oder ist hier schon was falsch: sJSONStr = “{”“name”":"“1235621"”,"“taxId”":1,"“mainDetail”":[{"“number”":"“12345"”}]}"

zu den Lizenzfragen: https://github.com/restsharp/RestSharp#license-apache-license-20 http://stackoverflow.com/questions/1007338/can-i-use-a-library-under-the-apache-software-license-2-0-in-a-commercial-applic zu deinem JSON String warum nutzt du nicht einfach diese Lib hier? http://nuget.org/packages/Newtonsoft.Json/ dann ich glaube dass man in vb.net um " auszugeben das ganze 4x schreiben muss also “”"" an die Request URL musst du auch noch die ArtikelID anhängen also zum Beispiel: sUri = "http://\*\*\*\*\*\*\*\*\*\*\*\*\*\*.de.shopware-hosting.com/api/articles/3/" klar geht es auch mit HttpWebRequest ich habe selbst eine Schnittstelle zu einer Warenwirtschaft programmiert welche die Daten per HttpWebRequest versendet. Ich habe Dir hier nur einen weiteren einfacheren Weg zeigen wollen.

Na ich habe schon vor später dann eine JSON Lib zu nutzen, existiert ja bereits… Der JSON String ist ja nur zum test da, die Anführungszeichen sollten stimmen. raus kommt dabei folgendes: “{“name”:“1235621”,“taxId”:1,“mainDetail”:[{“number”:“12345”}]}” restSharp bedeutet halt auch: wieder eine weitere dll die mit ausgelifert werden muss. Und ich sollte mich auf .NET-Bordmitteln beschränken. Und ich seh auch da noch keinen echten Vorteil von restSharp. Du hast eine Schnittstelle die mit HttpWebrequest einen Artikel überträgt? Kannst du dir mal meinen Code ansehen, vielleicht fällt dir da was auf. Irgendwas muss ich ja falsch machen. "an die Request URL musst du auch noch die ArtikelID anhängen also zum Beispiel: sUri = “http://**************.de.shopware-hosting.com/api/articles/3/” Was du mir damit jetzt sagen willst verstehe ich nicht wirklich? Ich möchte ja keinen Artikel abrufen, sondern einen neuen übertragen, dann doch ohne id. Oder versteh ich da was grundlegend falsch?

nein hast du recht :stuck_out_tongue: hab ich verwechselt.

bei mir sieht das so aus ''' ''' Sends the data. ''' ''' <param name="url">The URL. ''' <param name="method">The method. ''' <param name="data">The data. ''' <returns></returns> Private Function SendData(ByVal url As Uri, ByVal method As Method, Optional ByVal data As String = Nothing) ' Create a request using a URL that can receive a post. Dim request As HttpWebRequest = CType(WebRequest.Create(url), HttpWebRequest) request.UserAgent = My.Application.Info.AssemblyName ' Set the Method property of the request to POST. request.Method = method.ToString ' Create POST data and convert it to a byte array. ' Set the ContentType property of the WebRequest. request.ContentType = "application/json; charset=UTF-8" request.ContentLength = 0 ' Set the ContentLength property of the WebRequest. If Not IsNothing(data) Then request.ContentLength = StringToByteArray(data).Length ' Get the request stream. Dim dataStream As Stream = request.GetRequestStream() ' Write the data to the request stream. dataStream.Write(StringToByteArray(data), 0, StringToByteArray(data).Length) ' Close the Stream object. dataStream.Close() ' Get the response. Dim response As WebResponse = request.GetResponse() ' Display the status. Select Case CType(response, HttpWebResponse).StatusCode Case HttpStatusCode.OK Console.ForegroundColor = ConsoleColor.DarkGreen Console.WriteLine(CType(response, HttpWebResponse).StatusDescription & " (" & CType(response, HttpWebResponse).StatusCode & ")") Case Else Console.ForegroundColor = ConsoleColor.DarkRed Console.WriteLine(CType(response, HttpWebResponse).StatusDescription & " (" & CType(response, HttpWebResponse).StatusCode & ")") End Select Console.ResetColor() ' Get the stream containing content returned by the server. Dim str As Stream = response.GetResponseStream Dim reader As New StreamReader(str) Console.WriteLine(reader.ReadToEnd()) reader.Close() response.Close() End Function

1 „Gefällt mir“

danke dir! Aber wo findet die Authentifizierung statt? ApiUser und Apischlüssel sehe ich jetzt hier nirgens… Ansonsten seh ich da jetzt nichts, was grundsätzlich anders abläuft.

für die Auth nutze ich eine andere Funktion. der Auth Vorgang muss ja nur einmal passieren dann entsprechend den Login Cookie speichern und ab dort kann man dann immer wieder anfragen an die API stellen. Am Ende der Schleife (bei mehreren Artikeln) wird ein Logout geschickt. mein Code ist komplett anders aufgebaut als deiner ich denke da wirst du wohl selbst noch etwas probieren müssen. wegen dem ausliefern der zusätzlichen DLLs warum kompilest du diese nicht mit in dein Hauptprogramm?

aha interessant, wärst du so nett und haust mal den code block für die authetifizierung mit rein…

[quote=“kotoradeluxe”]Google ist dein Freund :stuck_out_tongue: Anstatt abrufen GET einfach anlegen POST oder zum Updaten PUT schicken entsprechend dann in den Request.Body dein JSON stecken request.AddParameter("name", "value"); // adds to POST or URL querystring based on Method so ähnlich dann nur nicht dass es ein Parameter ist sondern eben der Body an sich[/quote] Ich habe ein Problem beim schrieben eines neuen Artikels, mittels der Shopware API. Ich verwende den RestClient in Verbindung mit C#. Eine Abfrage der Artikel aus dem Shop funktioniert einwandfrei. Aber wenn ich versuche ein Artikel zu eröffnen erhalte ich immer folgende Fehler Struktur: { "success": false, "message": "Validation error", "errors": ["name: This value should not be blank", "tax: This value should not be blank", "mainDetail.number: This value should not be blank"] } Den Code welcher die Request absetzt ist folgender: public string WriteJsonRequest(string vJsonContent) { string lValidationMessage = ""; if (!ValidateData(out lValidationMessage)) { throw new ApplicationException(lValidationMessage); } var client = new RestClient(mUrl) { Authenticator = new DigestAuthenticator(mUser, mKey) }; var request = new RestRequest(mRessource, Method.POST); request.RequestFormat = DataFormat.Json; request.AddHeader("Content-Type", "application/json; charset=utf-8"); request.AddBody(vJsonContent); var response = client.Execute(request); if (response.ErrorException != null) throw new ApplicationException("Error", response.ErrorException); else { var content = response.Content; // raw content as string dynamic json = JsonConvert.DeserializeObject(content); return json.ToString(); } } Der Request-String sieht folgendermassen aus: { "name": "Test Artikel", "mainDetail": { "number": "SW10001" }, "tax": { "tax": "8.00" } } Leider habe ich weder Zugang zum Shop selber noch habe ich viel Ahnung von Json und Shopware. (Es handelt sich um ein Kunde, welcher sein Shop nun mit Shopware realisieren will) Ich muss ein Hilfsprogramm schreiben, damit der Shop aus Dynamics NAV bedient werden kann. Ich würde mich sehr freuen, wenn mir hier, in diesem Belangen, geholfen werden kann. Ich sehe nicht was ich falsch mache… Grüsse Kim Schröder

Hi Kim, ich bin aktuell in einer ähnlichen Siutation. Ich muss eine Schnittstelle zwischen Navision und Shopware realisieren. Dabei hänge ich an der gleichen Stelle. Ich antworte hier nur um dir einen Tipp zu geben. Die gewünschte Anforderung kann auch direkt aus Navision heraus realisiert werden. Eigentlich benötigst du kein eigenes Hilfsprogramm. Du kannst alles über die WinHttp.DLL machen. Z.b. Abruf von Daten: IF ISCLEAR(WinHttp) THEN CREATE(WinHttp); // WinHttp.SetProxy -> Evtl. notwendig WinHttp.OPEN(’ z.B. GET, POST, etc.’,‚ShopWare-URL‘);
WinHttp.SetCredentials(‚loginame‘,‚loginkey‘);
WinHttp.Send;

Ab hier solltest du das Result in eine TXT-Datei lesen oder direkt in NAV verarbeiten.
Ich schreibe es aktuell für meine „ersten“ Erfahrungen zunächst in ein Text-File.

istream := WinHttp.ResponseStream;
iBigText.READ(istream);
ifile.WRITEMODE(TRUE);
ifile.CREATE(‚C:\Test\Webshop\Test.txt‘);
ifile.CREATEOUTSTREAM(ostream);
iBigText.WRITE(ostream);
ifile.CLOSE;

Ich weiß jetzt nicht, ob es dir was hilft, da ich aus deinem Post entnehme, dass du nicht Navision programmiert. Aber evtl. hilft euch das weiter.

Ich habe aktuell noch Probleme mit ‚PUT‘ und ‚POST‘, da mir die Syntax dieses ominösen json-Strings nicht bekannt ist, welcher aber scheinbar sehr wichtig ist.
Ich finde (nach langer Suche) auch keine passende Dokumentation dazu.

Aufjeden fall kannst du diesen json-String direkt in das SEND geben.

Also z.B.
WinHttp.SEND(’’);

Aktuell bekomme ich aber noch folgende Meldung:

{„success“:false,„message“:„Tax by taxrate Array not found“}

VG
Don

Hi Don Wie Du richtig bemerkt hast, programmiere ich nicht NAV. Diese Aufgabe hat jemand ansders in unserem Unternehmen. Noch kurz zur Json Syntax, Anhand deiner Fehlermeldung… Ein Objekt definieren in Json innerhalb geschweifter Klammern {} Ein Array wird innerhalb eckiger Klammern definiert , worin jeweils auch wieder Objekte, resp. geschweifte Klammern geschrieben werden können. Eventuell hilft Dir das weiter. Gruss Kim

Ich bin ein Schritt weiter gekommen und konnte endlich ein Artikel erfolgreich eröffnen. Ich denke dies könnte für anderen Personen noch Interessant sein, desshalb schreibe ich hier meine Lösung: Funktioniert hat es am Ende, als ich den Rest Client von .NET in den Wind geschlagen habe. Ich mache die Request nun über ein ganz normalen HttpReguest ohne spezielle konfiguration. Lediglich die Anmeldeinformationen in die Credentials übergeben und den Json in den RequestStream schreiben. Folgender Codeauschnitt ist C#, zeigt jedoch wie vom Prinzip her vorgegangen werden muss. public string WriteJsonRequest2(string vJsonContent) { HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(mUrl + "/" + mRessource); request.Credentials = new NetworkCredential(mUser, mKey); request.Method = "POST"; request.ContentType = "text/plain;charset=utf-8"; System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding(); byte[] bytes = encoding.GetBytes(vJsonContent); request.ContentLength = bytes.Length; using (Stream requestStream = request.GetRequestStream()) { // Send the data. requestStream.Write(bytes, 0, bytes.Length); } string lResponse = ""; using (HttpWebResponse response = (HttpWebResponse)request.GetResponse()) { lResponse = response.StatusDescription; } return lResponse; } Folgender Json Code funktioniert in unserem System. Aber wiederum sollte es aufzeigen wie er aufgebaut werden soll/kann, damit er vom Shop gelesen werden kann. (Es ist lediglich ein Testartikel und es werden nicht alle möglichen Werte übergeben) [code] { “tax”: 1, “name”: “Fifa 14 Ultimate Edition PS3”, “description”: “”, “descriptionLong”: “Ein exklusives FIFA 14 Steelbook”, “active”: true, “pseudoSales”: 0, “highlight”: false, “keywords”: “”, “priceGroupActive”: false, “lastStock”: false, “crossBundleLook”: 0, “notification”: false, “template”: “”, “mode”: 0, “availableFrom”: null, “availableTo”: null, “configuratorSet”: null, “mainDetail”: { “number”: “KS10001”, “supplierNumber”: “”, “kind”: 1, “additionalText”: “”, “active”: 1, “inStock”: 10000, “stockMin”: 0, “weight”: “0.000”, “width”: null, “len”: null, “height”: null, “ean”: “3289742398283”, “position”: 0, “minPurchase”: null, “purchaseSteps”: null, “maxPurchase”: null, “purchaseUnit”: null, “referenceUnit”: null, “packUnit”: “”, “shippingFree”: true, “releaseDate”: “2013-11-30T00:00:00+0100”, “shippingTime”: “”, “prices”: [{ “customerGroupKey”: “EK”, “from”: 1, “to”: “beliebig”, “price”: 67.310924369748, “pseudoPrice”: 74.789915966387, “basePrice”: 0, “percent”: 0 }], “attribute”: { “attr1”: “”, “attr2”: “”, “attr3”: “”, “attr4”: “”, “attr5”: “”, “attr6”: “”, “attr7”: “”, “attr8”: “”, “attr9”: “”, “attr10”: “Playstation 3”, “attr11”: “D/F/I”, “attr12”: “D/F/I”, “attr13”: “”, “attr14”: “”, “attr15”: “”, “attr16”: “”, “attr17”: null, “attr18”: “”, “attr19”: “”, “attr20”: “”, “swagAttr21”: null, “swagAttr22”: null, “swagAttr23”: null, “swagAttr24”: null, “swagAttr25”: null, “swagAttr26”: null, “swagAttr27”: null, “swagAttr28”: null, “swagAttr29”: null, “swagAttr30”: null, “swagAttr31”: null, “swagAttr32”: null, “swagAttr33”: null, “swagAttr34”: null, “swagAttr35”: null, “swagAttr36”: null, “swagAttr37”: null, “swagAttr38”: null, “swagAttr39”: null, “swagAttr40”: null } }, “tax”: { “tax”: “8.00”, “name”: “8%” }, “categories”: { “182”: { “name”: “Neuheiten” }, “367”: { “name”: “Sport” } }, “links”: , “images”: [{ “description”: “Fifa 14 Ultimate Edition f\u00fcr PS3”, “path”: “fifa14ps3”, “main”: 1, “position”: 1, “width”: 0, “height”: 0, “relations”: “”, “extension”: “jpg”, “parentId”: null, “mediaId”: 1 }], “downloads”: , “related”: , “propertyValues”: , “similar”: , “customerGroups”: , “supplier”: { “name”: “Electronic Arts”, “image”: “”, “link”: “”, “description”: "

Beschreibung" }, “details”: , “propertyGroup”: null } [/code] Nachfolgend noch ein Json String welcher, zumindest in unserem System, die minimalen Angaben zum erstellen eines Artikles beinhaltet. { "name": "Fifa 14 Ultimate Edition PS3", "mainDetail": { "number": "KS10014" }, "tax": { "tax": "8.00", "name": "8%" } } Ich hoffe dieser Beitrag hilft noch einigen Verzweifelten und ich wünsche euch allen viel Erfolg… Ein Artikel kann nur erstellt werden wenn der Wert: “number”: “” innerhalb des mainDetail, eindeutig ist. Also wenn dieser nicht schon im Shop vorhanden ist. Ansonsten habe ich jeweils ein Server Error 500 zurückbekommen.

Grüsse Kim Schröder

Hi DonAlfredo, läuft bei Dir die Navisionanbindung über WinHttp? Kann ich von Dir die Kernfunktion bekommen? Deinen hier geposteter Code habe ich nicht zum Laufen bekommen, aber schon mal schönen Dank für den richtigen Schups.

Guten Tag und vielen Dank an alle VorPoster. Leider gelingt es mir nicht das den funktionierenden Minimalstring für das Anlegen von Artikeln von Kim zum Laufen zu bekommen. Ich bekomme als Antwort immer: {“success”:false,“message”:“Invalid method or invalid json string.”} Ich weiss leider nicht wie ich in c# oder auch vb.net JSON String erzeugen muss, vor allem das enthaltene Array macht mir Schwierigkeiten. Hat zufällig jemand einen funktionierenden Codeschnipsel welcher das Erzeugen eines JSON Strings für das anlegen eines Artikels zur Aufgabe hat ? Mein JSON String sieht momentan so aus: { “name”: “Fifa 14 Ultimate Edition PS3”, “mainDetail”: [{ “number”: “KS10014” }], “tax”: [{ “tax”: “8.00”, “name”: “8%” }] } Vielen Dank Michael