En utilisant Fiddler, je peux passer dans le corps
someXml = ThisShouldBeXml
puis dans le contrôleur
[HttpPost]
public ActionResult Test(object someXml)
{
return Json(someXml);
}
obtient ces données sous forme de chaîne
Comment faire en sorte que fiddler passe le code XML à ActionController de MVC? Si j'essaie de définir la valeur dans le corps en tant que fichier XML brut, cela ne fonctionne pas.
Et pour les points bonus, comment puis-je utiliser VBScript/ASP classique?
J'ai actuellement
DataToSend = "name=JohnSmith"
Dim xml
Set xml = server.Createobject("MSXML2.ServerXMLHTTP")
xml.Open "POST", _
"http://localhost:1303/Home/Test", _
False
xml.setRequestHeader "Content-Type", "application/x-www-form-urlencoded"
xml.send DataToSend
Vous ne pouvez pas transmettre directement des données XML sous forme de fichier au contrôleur MVC. Une des meilleures méthodes consiste à transmettre des données XML en tant que flux avec publication HTTP.
Pour poster du XML,
Référez-vous à this stackoverflow post pour plus de détails sur la publication de XML sur MVC Controller
Pour récupérer le code XML dans le contrôleur, utilisez la méthode suivante
[HttpPost]
public ActionResult Index()
{
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
if (response.StatusCode == HttpStatusCode.OK)
{
// as XML: deserialize into your own object or parse as you wish
var responseXml = XDocument.Load(response.GetResponseStream());
//in responseXml variable you will get the XML data
}
}
Cela semble être le moyen de payer XML à un contrôleur MVC
Comment passer XML en tant que POST à un ActionResult dans ASP MVC .NET
J'ai essayé de faire en sorte que cela fonctionne avec l'API WEB, mais je n'ai pas pu utiliser le contrôleur MVC.
Afin de transmettre les données sous forme de fichier dans MVC, vous devez créer votre propre outil de formatage de type de support pour gérer le texte brut. Ajoutez ensuite le formateur à la section config.
Pour utiliser le nouveau formateur, spécifiez le type de contenu pour ce formateur, par exemple, text/plain .
Exemple de formateur pour le texte
using System;
using System.Net.Http.Formatting;
using System.Net.Http.Headers;
using System.Threading.Tasks;
using System.IO;
using System.Text;
namespace SampleMVC.MediaTypeFormatters
{
public class TextMediaTypeFormmatter : XmlMediaTypeFormatter
{
private const int ByteChunk = 1024;
private UTF8Encoding StringEncoder = new UTF8Encoding();
public TextMediaTypeFormmatter()
{
base.UseXmlSerializer = true;
SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/plain"));
}
public override bool CanReadType(Type type)
{
if (type == typeof(string))
{
return true;
}
return false;
}
public override bool CanWriteType(Type type)
{
if (type == typeof(string))
{
return true;
}
return false;
}
public override Task<object> ReadFromStreamAsync(Type type, Stream readStream, System.Net.Http.HttpContent content, IFormatterLogger formatterLogger)
{
StringBuilder StringData = new StringBuilder();
byte[] StringBuffer = new byte[ByteChunk];
int BytesRead = 0;
Task<int> BytesReadTask = readStream.ReadAsync(StringBuffer, 0, ByteChunk);
BytesReadTask.Wait();
BytesRead = BytesReadTask.Result;
while (BytesRead != 0)
{
StringData.Append(StringEncoder.GetString(StringBuffer, 0, BytesRead));
BytesReadTask = readStream.ReadAsync(StringBuffer, 0, ByteChunk);
BytesReadTask.Wait();
BytesRead = BytesReadTask.Result;
}
return Task<object>.Run(() => BuilderToString(StringData));
}
private object BuilderToString(StringBuilder StringData)
{
return StringData.ToString();
}
public override Task WriteToStreamAsync(Type type, object value, Stream writeStream, System.Net.Http.HttpContent content, System.Net.TransportContext transportContext)
{
byte[] StringBuffer = StringEncoder.GetBytes((string)value);
return writeStream.WriteAsync(StringBuffer, 0, StringBuffer.Length);
}
}
}
Méthode du contrôleur:
[HttpPost]
public async Task<HttpResponseMessage> UsingString([FromBody]string XmlAsString)
{
if (XmlAsString == null)
{
return this.Request.CreateResponse(HttpStatusCode.BadRequest);
}
return this.Request.CreateResponse(HttpStatusCode.OK, new { });
}
Configuration dans la méthode de registre WebApiConfig.cs:
config.Formatters.Add(new TextMediaTypeFormmatter());
En-têtes de violoneux:
User-Agent: Fiddler
Content-Type: text/plain
MVC Controller n’est pas idéal pour ce type de traitement des demandes, mais c’était là la tâche à accomplir. Allons-y. Ayons un XML que je dois accepter:
<document>
<id>123456</id>
<content>This is document that I posted...</content>
<author>Michał Białecki</author>
<links>
<link>2345</link>
<link>5678</link>
</links>
</document>
J'ai essayé quelques solutions avec la désérialisation de paramètres intégrée, mais aucune ne semble fonctionner, et finalement, j'ai procédé à la désérialisation d'une requête dans un corps de méthode. J'ai créé une classe générique d'assistance pour cela:
public static class XmlHelper
{
public static T XmlDeserializeFromString<T>(string objectData)
{
var serializer = new XmlSerializer(typeof(T));
using (var reader = new StringReader(objectData))
{
return (T)serializer.Deserialize(reader);
}
}
}
J'ai décoré mon DTO avec les attributs XML:
[XmlRoot(ElementName = "document", Namespace = "")]
public class DocumentDto
{
[XmlElement(DataType = "string", ElementName = "id")]
public string Id { get; set; }
[XmlElement(DataType = "string", ElementName = "content")]
public string Content { get; set; }
[XmlElement(DataType = "string", ElementName = "author")]
public string Author { get; set; }
[XmlElement(ElementName = "links")]
public LinkDto Links { get; set; }
}
public class LinkDto
{
[XmlElement(ElementName = "link")]
public string[] Link { get; set; }
}
Et utilisé tout cela dans un contrôleur:
public class DocumentsController : Controller
{
// documents/sendDocument
[HttpPost]
public ActionResult SendDocument()
{
try
{
var requestContent = GetRequestContentAsString();
var document = XmlHelper.XmlDeserializeFromString<DocumentDto>(requestContent);
return new HttpStatusCodeResult(HttpStatusCode.OK);
}
catch (System.Exception)
{
// logging
return new HttpStatusCodeResult(HttpStatusCode.InternalServerError);
}
}
private string GetRequestContentAsString()
{
using (var receiveStream = Request.InputStream)
{
using (var readStream = new StreamReader(receiveStream, Encoding.UTF8))
{
return readStream.ReadToEnd();
}
}
}
}
Pour l'utiliser, il suffit d'envoyer une demande en utilisant par exemple Postman. J'envoie la demande POST à http://votredomaine.com/documents/sendDocument endpoint avec le corps xml mentionné ci-dessus. Un détail qui mérite d'être mentionné est un en-tête. Ajouter un type de contenu: text/xml ou une requête de travail.
Vous pouvez voir le post entier sur mon blog: http://www.michalbialecki.com/2018/04/25/accept-xml-request-in-asp-net-mvc-controller/