2016-06-06 8 views
2

Ich benutze Aspera Enterprise Server/Aspera connect für Uploads von Benutzern. Diese Lösung bietet eine Start/Stopp-Validierung dieser Uploads und sendet eine JSON-formatierte HTTP-Anfrage an einen Webservice, den ich angeben kann.Ersetze ungültige Zeichen in http Anfrage Körper in einem C# .net Webservice

Das Problem ist, dass all dies eingerichtet ist, so dass aspera einen Domänenbenutzer für die Authentifizierung verwendet und dieser Domänenbenutzer als "TD \ asperaTransfer" gespeichert wird und es scheint, ich kann die Schreibweise des Benutzers und der aspera nicht ändern Die Software reinigt das JSON vor/während der Serialisierung der Daten nicht.

Das bedeutet, meine Webservice einen Antrag mit einem Körper wie diese bekommt:

{ 
    "startstop": "stop", 
    "session_id": "99eb1fac-da7b-41ac-83ee-b3c5f", 
    "host": "10.22.64.6", 
    "client_ip": "10.20.21.80", 
    "user": "TD\asperaTransfer", 
    "user_id": "0", 
    "direction": "recv", 
    "target_rate_kbps": "1000", 
    "min_rate_kbps": "0", 
    "rate_policy": "fair", 
    "cipher": "aes-128", 
    "file": "F:\\UploadTest\\Penn and Teller explain Sleight of hand.mp4", 
    "size": "2318300", 
    "start_byte": "0", 
    "end_byte": "2318300", 
    "file_name_encoding": "utf8", 
    "file_csum_type": "none", 
    "cookie" : "True|c4308ab7-5772-4549-b2ae-8145d1e43230|master_cbc9d569-4154-4b10-8b3b-5fe8e68197b1.mp4" 
} 

Wie Sie den Dateipfad richtig ist entkommen zu sehen. Dies liegt daran, dass ein anderer Teil der Software den Dateipfad in der Anfrage festlegt. Immer noch die Domäne "\" ist nicht maskiert und damit jedes Mal, wenn .net versucht, in irgendeiner Weise zu deserialisieren, bekomme ich eine XmlException "Unerwartetes Zeichen 'a'".

Also meine Frage ist:

Gibt es eine Möglichkeit „TD \ asperaTransfer“ entweder ersetzen mit dem richtig entkommen „TD \\ asperaTransfer“ oder irgendeine Art und Weise, es nicht deserialisieren, sondern abrufen nur eine String-Darstellung der Körper, mit dem ich dann arbeiten kann?

Mein letzter Versuch dafür war, eine MessageInspector Klasse zu erstellen, die IDispatchMessageInspector implementiert und den Körper in der AfterReceiveRequest() Methode ersetzen.

Noch habe ich das Problem, dass ich keine Ahnung, wie an dem Körper Inhalt zu erhalten, ohne irgendeine Art von Deserializer zu verwenden, die dann wieder die XmlException werfen würden.

Edit:

Also ja - der Körper ist eine json formatierten String, aber die Art und Weise .NET Requests HTTP empfängt, ist als ein Message-Objekt in einem XML-Soap-Umschlag, so dass der Körper Zeichenfolge erhalten Ich habe einen XML-Deserializer zu verwenden, aber wenn ich das tue, bekomme ich die XML-Exception. Sorry für die XML/Json-Verwirrung.

Ich denke auch, es ist seltsam, dass ich eine XML-Ausnahme bekomme, aber es sagt "Ungültiges Zeichen 'a'" - und wenn ich es mit einer anderen Anfrage wie TD \ zoolander teste, dann heißt es das ungültige Zeichen ist 'z' also nehme ich an, dass es mit dem umgekehrten Schrägstrich zu tun hat, obwohl es nicht als Escape-Zeichen in XML zählt.

Wenn es schon einen Weg gibt, die HTTP-Anforderung abzurufen und als Protokoll zu speichern, so können Sie es für Debugging-Zwecke sehen - das ist, was ich versuche zu tun, kann aber nicht das .NET Framework um es zu tun, weil es die HTTP-Anforderung in einem Nachrichtenobjekt und damit in XML umschließt.

Ich brauche nicht einmal den ganzen Körper, nur den Wert des "Cookie" -Schlüssels. Der Rest ist nutzlos für mich, aber selbst wenn ich versuche, einfach zu springen, iteriert er über TD \ und löst die Ausnahme aus.

+0

Sie sollten ein C# (POCO) -Objekt erstellen und dann mit 'System.Web.Script.Serialization.JavaScriptSerializer' Ihr Objekt als JSON für den Hauptteil formatieren. Weitere Informationen: https://msdn.microsoft.com/en-us/library/system.web.script.serialization.javascriptserializer(v=vs.110).aspx –

+0

Zwei Dinge ** Erstens: ** Wenn ich könnte bekomme eine String-Repräsentation des Rumpfes Ich hätte das Problem nicht, daher hilft mir dieser Deserializer, der eine Zeichenkette als Eingabe verwendet, nicht oder ich sehe nicht, wie mir das hilft, da die Message-Klasse immer in XML und in eingepackt ist Der Hauptteil dieser Nachricht ist die json-formatierte Zeichenfolge. Ich kann diese Zeichenfolge nicht ohne Ausnahme abrufen. Wenn ich die Zeichenfolge bekomme, wäre es einfach. ** Zweitens: ** Von der Doku Sie verknüpft - "Json.NET sollte Serialisierung und Deserialisierung verwendet werden. Stellt Serialisierung und Deserialisierung Funktionalität für AJAX-fähige Anwendungen." – juli0r

+1

Das ist JSON, aber Sie sprechen darüber, eine XML-Ausnahme zu bekommen, und eine mit einer ungewöhnlichen Nachricht (XML macht nichts mit dem Backslash-Escaping). Was ist der * gesamte * Nachrichtentext einschließlich des Wrappings und wie sieht Ihre Service-Bindung aus? –

Antwort

0

Also das Problem war ein benutzerdefinierter Content-Typ-Mapper, den ich bereits für den Webservice im alten Datencenter in Aspera geschrieben hatte, weil die HTTP-Anfrage auch keinen Content-Type-Set hat. Um also die Anfrage zu deserialisieren, habe ich den Inhaltstyp auf JSON gesetzt, unabhängig davon, was in der Kopfzeile war.

Für die messageInspector stelle ich es zurück zu roh

Im AfterReceiveRequest ich die Anfrage wie folgt lesen jetzt (wahrscheinlich auch helfen würde, zu entfernen):

private string ReadRawBody(ref Message message) 
    { 
     XmlDictionaryReader bodyReader = message.GetReaderAtBodyContents(); 
     bodyReader.ReadStartElement("Binary"); 
     byte[] bodyBytes = bodyReader.ReadContentAsBase64(); 
     string messageBody = Encoding.UTF8.GetString(bodyBytes); 

     // Now to recreate the message 
     MemoryStream ms = new MemoryStream(); 
     XmlDictionaryWriter writer = XmlDictionaryWriter.CreateBinaryWriter(ms); 
     writer.WriteStartElement("Binary"); 
     writer.WriteBase64(bodyBytes, 0, bodyBytes.Length); 
     writer.WriteEndElement(); 
     writer.Flush(); 
     ms.Position = 0; 
     XmlDictionaryReader reader = XmlDictionaryReader.CreateBinaryReader(ms, XmlDictionaryReaderQuotas.Max); 
     Message newMessage = Message.CreateMessage(reader, int.MaxValue, message.Version); 
     newMessage.Properties.CopyProperties(message.Properties); 
     message = newMessage; 

     return messageBody; 
    } 

Mit dieser String-Darstellung des Körpers I kann funktionieren, ersetzen Sie den TD \ asperaTransfer und bearbeiten Sie dann die Anfrage wie früher.

Das Problem war ein benutzerdefinierter Inhaltstyp-Mapper, der immer den Inhaltstyp auf JSON setzte und somit versuchte .NET, es als JSer zu deserialisieren. Danke für die Fragen zur Klärung der Kommentare zu "\", dass es kein Sonderzeichen ist und was der Dienstleistungsvertrag dazu bringt, die richtigen Dinge nachzuschlagen.