ViewModelをシリアル化し、リモートのサードパーティ製のサーバーにデータ処理用に送信しようとしているASP.NET MVC 5アプリケーションがあります。私は何が間違っているのか正確にはわかりませんが、以下は私が試したコードです。ViewModelをXMLにシリアル化してリモートサーバーに送信するにはどうすればよいですか?
はまず、ここで私はViewModelにをシリアル化し、リモートサーバーに送信しようとしていた中で、私のコントローラでPOST
方法です:
[HttpPost]
public ActionResult Index(Transmission t)
{
ViewBag.ErrorMessage = "";
ViewBag.OtherMessage = "";
try
{
//serialize the ViewModel
XmlResult xrs = new XmlResult(t);
XDocument xdoc = XDocument.Parse(xrs.ToString());
Stream stream = new MemoryStream(); //the memory stream to be used to save the xdoc
XmlActionResult xar = new XmlActionResult(xdoc);
xdoc.Save(stream);
//xrs.ExecuteResult(ControllerContext);
//POST the data to the external URL
var url = "theUrl";
var PostData = xar;
var Req = (HttpWebRequest)WebRequest.Create(url);
Req.ContentType = "application/xml";
Req.Method = "POST";
Req.Timeout = 60000;
Req.KeepAlive = false;
//build the string to send
StringBuilder sb = new StringBuilder();
using(StreamReader sr = new StreamReader(stream))
{
string line;
while((line = sr.ReadLine()) != null)
{
sb.AppendLine(line);
}
byte[] postBytes = Encoding.ASCII.GetBytes(sb.ToString());
Req.ContentLength = postBytes.Length;
using (Stream requestStream = Req.GetRequestStream())
{
requestStream.Write(postBytes, 0, postBytes.Length);
requestStream.Close();
}
using (var response = (HttpWebResponse)Req.GetResponse())
{
ViewBag.OtherMessage = response.ToString();
return View("Error"); //TODO: change this to success when I get the 500 error fixed
}
}
}
catch (Exception ex)
{
string message = ex.Message;
ViewBag.ErrorMessage = ex.Message;
return View("Error");
}
}
}
あなたが上見ることができるように、私は2つのクラスを使用しています、それぞれXmlActionResult
とXmlResult
と呼ばれます。 XmlResult
クラスは、ViewModelのシリアル化に使用されています。ここXmlResult
クラスの実装です:
public class XmlResult : ActionResult
{
private object objectToSerialize;
/// <summary>
/// Initializes a new instance of the <see cref="XmlResult"/> class.
/// </summary>
/// <param name="objectToSerialize">The object to serialize to XML.</param>
public XmlResult(object objectToSerialize)
{
this.objectToSerialize = objectToSerialize;
}
/// <summary>
/// Gets the object to be serialized to XML.
/// </summary>
public object ObjectToSerialize
{
get { return objectToSerialize; }
}
/// <summary>
/// Serializes the object that was passed into the constructor to XML and writes the corresponding XML to the result stream.
/// </summary>
/// <param name="context">The controller context for the current request.</param>
public override void ExecuteResult(ControllerContext context)
{
if (objectToSerialize != null)
{
context.HttpContext.Response.Clear();
var xs = new System.Xml.Serialization.XmlSerializer(objectToSerialize.GetType());
context.HttpContext.Response.ContentType = "xml";
xs.Serialize(context.HttpContext.Response.Output, objectToSerialize);
}
}
}
XmlResult
クラスはViewModelにシリアル化した後、私はXmlActionResult
クラスを使用してXDocument
を作成しようとしています。ここXmlActionResult
クラスの実装です:
public sealed class XmlActionResult : ActionResult
{
private readonly XDocument _document;
public Formatting Formatting { get; set; }
public string MimeType { get; set; }
public XmlActionResult(XDocument document)
{
if (document == null)
throw new ArgumentNullException("document");
_document = document;
// Default values
MimeType = "text/xml";
Formatting = Formatting.None;
}
public override void ExecuteResult(ControllerContext context)
{
context.HttpContext.Response.Clear();
context.HttpContext.Response.ContentType = MimeType;
using (var writer = new XmlTextWriter(context.HttpContext.Response.OutputStream, Encoding.UTF8) { Formatting = Formatting })
_document.WriteTo(writer);
}
}
私は私の最初の問題はどこにあるか、これがあると信じています。シリアライズされたViewModelオブジェクトt
からXmlResult
クラスを使用してXDocument
を作成しますが、 "ルートレベルのデータが無効です。ライン1、ポジション1"というエラーが表示されます。 XDocument
クラスでシリアル化されたViewModelオブジェクトの解析に問題があることを示します。私はここで何をやったのですか?
次に、MemoryStream
にXDocument
(正常に作成された後)を保存しようとしています。考え方は、StreamReader
を介してMemoryStream
に保存されたXDocument
にアクセスしているStringBuilder
オブジェクトからbyte
アレイを構築し、HttpWebRequest
オブジェクトを介してリモートサーバーに送信することです。しかし、私は上記のエラーのおかげで、まだこれを得ていません。
ご協力いただきまして誠にありがとうございます。私が必要とするならば、私はこの全体のアプローチを変えたいと思っています。私は最初の部分が働いても後者の部分がうまくいくとは確信していないので、どんなアドバイスも耳を傾けます。ありがとうございました。
アップデート:例外の詳細について
例外は、このラインで投げている:
XDocument xdoc = XDocument.Parse(xrs.ToString());
innerException
はnullです。 Message
は、 "ルートレベルのデータが無効です。ライン1、ポジション1"です。
*ルートレベルのデータは無効です。 1行1位* - 例外の型、メッセージ、トレースバック、内部例外を含む例外の完全な 'ToString()'出力を共有できますか?どの列に例外がスローされますか?あなたはあなたの質問を[mcve]に還元できますか? – dbc
@dbc待って。 – ic3man7019
@dbc例外に関する詳細情報が提供されています。 – ic3man7019