C# 如何将ViewModel序列化为XML并将其发送到远程服务器?
我有一个ASP.NET MVC 5应用程序,我试图在其中序列化我的ViewModel并将其发送到远程第三方服务器进行数据处理。我不确定我做错了什么,但下面是我尝试过的代码 首先,这里是控制器中的C# 如何将ViewModel序列化为XML并将其发送到远程服务器?,c#,xml,asp.net-mvc,http,serialization,C#,Xml,Asp.net Mvc,Http,Serialization,我有一个ASP.NET MVC 5应用程序,我试图在其中序列化我的ViewModel并将其发送到远程第三方服务器进行数据处理。我不确定我做错了什么,但下面是我尝试过的代码 首先,这里是控制器中的POST方法,在该方法中,我尝试序列化ViewModel并将其发送到远程服务器: [HttpPost] public ActionResult Index(Transmission t) { ViewBag.ErrorMessage = "";
POST
方法,在该方法中,我尝试序列化ViewModel并将其发送到远程服务器:
[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");
}
}
}
正如您在上面看到的,我使用了两个类,分别称为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);
}
}
}
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);
}
}
我相信这是我的第一个问题所在。我想使用XmlResult
类从序列化的ViewModel对象创建XDocument
,在本例中,使用XmlResult
类创建一个XDocument
,但我收到一个错误,提示“根级别的数据无效。第1行,位置1。”这说明XDocument
类在解析序列化的ViewModel对象时遇到问题。我做错了什么
接下来,我尝试将XDocument
(成功创建后)保存在内存流中。其思想是从一个StringBuilder
对象构建一个byte
数组,该对象通过StreamReader
访问XDocument
,该文档保存在MemoryStream
中,并通过HttpWebRequest
对象将其发送到远程服务器。然而,由于上面的错误,我还没有走到这一步
非常感谢您的帮助。如果需要,我愿意改变整个方法。我不确定后一部分是否会起作用,即使我让前一部分起作用,所以任何建议都会得到重视。多谢各位
更新:有关异常的更多信息
正在此行引发异常:
XDocument xdoc = XDocument.Parse(xrs.ToString());
innerException
为空。
消息是“根级别的数据无效。第1行,位置1。”公共异步任务索引(传输t)
{
ViewBag.ErrorMessage=“”;
ViewBag.OtherMessage=“”;
尝试
{
var xmlSerializer=新的xmlSerializer(typeof(传输));
使用(StringWriter sw=new StringWriter())
{
serializer.Serialize(sw,t);
var contentData=sw.ToString();
var httpContent=newstringcontent(contentData,Encoding.UTF8,“application/xml”);
var httpClient=新的httpClient();
httpClient.Timeout=新的时间跨度(0,1,0);
var response=wait-httpClient.PostAsync(“,httpContent”);
ViewBag.OtherMessage=wait response.Content.ReadAsStringAsync();
return View(“Error”);//TODO:在修复500错误后将此更改为success
}
}
捕获(例外情况除外)
{
字符串消息=例如消息;
ViewBag.ErrorMessage=例如消息;
返回视图(“错误”);
}
}
公共异步任务索引(传输t)
{
ViewBag.ErrorMessage=“”;
ViewBag.OtherMessage=“”;
尝试
{
var xmlSerializer=新的xmlSerializer(typeof(传输));
使用(StringWriter sw=new StringWriter())
{
serializer.Serialize(sw,t);
var contentData=sw.ToString();
var httpContent=newstringcontent(contentData,Encoding.UTF8,“application/xml”);
var httpClient=新的httpClient();
httpClient.Timeout=新的时间跨度(0,1,0);
var response=wait-httpClient.PostAsync(“,httpContent”);
ViewBag.OtherMessage=wait response.Content.ReadAsStringAsync();
return View(“Error”);//TODO:在修复500错误后将此更改为success
}
}
捕获(例外情况除外)
{
字符串消息=例如消息;
ViewBag.ErrorMessage=例如消息;
返回视图(“错误”);
}
}
根级别的数据无效。第1行,位置1。-您能否共享异常的完整ToString()
输出,包括异常类型、消息、回溯和内部异常?在哪一行抛出异常?你能把你的问题简化成一个问题吗?@dbc当然可以。请稍候。@dbc已提供有关异常的详细信息。请将xrs.ToString()放入变量中,以查看XDocument试图解析的内容。XmlResult执行此操作,它只写入http响应流。根级别的数据无效。第1行,位置1。-您能否共享异常的完整ToString()
输出,包括异常类型、消息、回溯和内部异常?在哪一行抛出异常?你能把你的问题简化成一个问题吗?@dbc当然可以。请稍候。@dbc已提供有关异常的详细信息。请将xrs.ToString()放入变量中,以查看XDocument试图解析的内容。XmlResult执行此操作,它只写入http响应流。这是正确的解决方案。我只需要做一些更改,这样XML编码就不会出现在XML数据中,但这是正确的。非常感谢。“这非常有帮助。”弗兰是对的。我做了很多XmlSerializer会为我做的事情。我误解了XmlResult
和XmlActionResult
类在做什么。事实证明,我根本不需要这些。这是正确的解决方案。我只需要做一些更改,这样XML编码就不会出现在XML数据中,但这是正确的。非常感谢。“这非常有帮助。”弗兰是对的。我做了很多XmlSerializer会为我做的事情。我误解了XmlResult
和
public async Task<ActionResult> Index(Transmission t)
{
ViewBag.ErrorMessage = "";
ViewBag.OtherMessage = "";
try
{
var xmlSerializer = new XmlSerializer(typeof(Transmission));
using (StringWriter sw = new StringWriter())
{
xmlSerializer.Serialize(sw, t);
var contentData = sw.ToString();
var httpContent = new StringContent(contentData, Encoding.UTF8, "application/xml");
var httpClient = new HttpClient();
httpClient.Timeout = new TimeSpan(0, 1, 0);
var response = await httpClient.PostAsync("", httpContent);
ViewBag.OtherMessage = await response.Content.ReadAsStringAsync();
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");
}
}