use*_*331 8 c# xml sql-server asp.net
我从存储过程中获取XML输出.我想要做的是获取XML并通过ASP.NET传递出来:
public XmlDocument GetPunchListXml(string communityDesc)
{
try
{
using (connection = new SqlConnection(connectionString))
{
connection.Open();
using (SqlCommand command = new SqlCommand("GetPunchList", connection))
{
command.CommandType = CommandType.StoredProcedure;
SqlParameter parameter1 = new SqlParameter("@communityDesc", SqlDbType.VarChar);
parameter1.Value = communityDesc;
parameter1.Direction = ParameterDirection.Input;
command.Parameters.Add(parameter1);
var doc = new XmlDocument();
var reader = command.ExecuteXmlReader();
if (reader.Read())
{
doc.Load(reader);
}
return doc;
}
}
}
finally
{
connection.Close();
}
}
Run Code Online (Sandbox Code Playgroud)
但我一直收到这些错误:
<Error>
<Message>An error has occurred.</Message>
<ExceptionMessage>
The 'ObjectContent`1' type failed to serialize the response body for content type 'application/xml; charset=utf-8'.
</ExceptionMessage>
<ExceptionType>System.InvalidOperationException</ExceptionType>
<StackTrace/>
<InnerException>
<Message>An error has occurred.</Message>
<ExceptionMessage>
Type 'System.Xml.XmlDocument' is an invalid collection type since it does not have a valid Add method with parameter of type 'System.Object'.
</ExceptionMessage>
<ExceptionType>
System.Runtime.Serialization.InvalidDataContractException
</ExceptionType>
<StackTrace>
at System.Runtime.Serialization.DataContract.DataContractCriticalHelper.ThrowInvalidDataContractException(String message, Type type)
at WriteArrayOfanyTypeToXml(XmlWriterDelegator , Object , XmlObjectSerializerWriteContext , CollectionDataContract )
at System.Runtime.Serialization.CollectionDataContract.WriteXmlValue(XmlWriterDelegator xmlWriter, Object obj, XmlObjectSerializerWriteContext context)
at System.Runtime.Serialization.XmlObjectSerializerWriteContext.WriteDataContractValue(DataContract dataContract, XmlWriterDelegator xmlWriter, Object obj, RuntimeTypeHandle declaredTypeHandle)
at System.Runtime.Serialization.XmlObjectSerializerWriteContext.SerializeWithoutXsiType(DataContract dataContract, XmlWriterDelegator xmlWriter, Object obj, RuntimeTypeHandle declaredTypeHandle)
at System.Runtime.Serialization.DataContractSerializer.InternalWriteObjectContent(XmlWriterDelegator writer, Object graph, DataContractResolver dataContractResolver)
at System.Runtime.Serialization.DataContractSerializer.InternalWriteObject(XmlWriterDelegator writer, Object graph, DataContractResolver dataContractResolver)
at System.Runtime.Serialization.XmlObjectSerializer.WriteObjectHandleExceptions(XmlWriterDelegator writer, Object graph, DataContractResolver dataContractResolver)
at System.Runtime.Serialization.DataContractSerializer.WriteObject(XmlWriter writer, Object graph)
at System.Net.Http.Formatting.XmlMediaTypeFormatter.WriteToStream(Type type, Object value, Stream writeStream, HttpContent content)
at System.Net.Http.Formatting.XmlMediaTypeFormatter.WriteToStreamAsync(Type type, Object value, Stream writeStream, HttpContent content, TransportContext transportContext, CancellationToken cancellationToken)
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
at System.Web.Http.WebHost.HttpControllerHandler.<WriteBufferedResponseContentAsync>d__1b.MoveNext()
</StackTrace>
</InnerException>
</Error>
Run Code Online (Sandbox Code Playgroud)
我究竟做错了什么?我试图获取XML的方式是否有问题,或者是XML本身的问题?
我尝试过以下方法:
var doc = new XmlDocument();
string s = "";
using (XmlReader reader = command.ExecuteXmlReader())
{
while (reader.Read())
{
//doc.Load(reader);
s = reader.ReadOuterXml();
doc.LoadXml(s);
}
}
return doc;
Run Code Online (Sandbox Code Playgroud)
并得到这些错误:
<Error>
<Message>An error has occurred.</Message>
<ExceptionMessage>
The 'ObjectContent`1' type failed to serialize the response body for content type 'application/xml; charset=utf-8'.
</ExceptionMessage>
<ExceptionType>System.InvalidOperationException</ExceptionType>
<StackTrace/>
<InnerException>
<Message>An error has occurred.</Message>
<ExceptionMessage>
Type 'System.Xml.XmlDocument' is an invalid collection type since it does not have a valid Add method with parameter of type 'System.Object'.
</ExceptionMessage>
<ExceptionType>
System.Runtime.Serialization.InvalidDataContractException
</ExceptionType>
<StackTrace>
at System.Runtime.Serialization.DataContract.DataContractCriticalHelper.ThrowInvalidDataContractException(String message, Type type) at WriteArrayOfanyTypeToXml(XmlWriterDelegator , Object , XmlObjectSerializerWriteContext , CollectionDataContract ) at System.Runtime.Serialization.CollectionDataContract.WriteXmlValue(XmlWriterDelegator xmlWriter, Object obj, XmlObjectSerializerWriteContext context) at System.Runtime.Serialization.XmlObjectSerializerWriteContext.WriteDataContractValue(DataContract dataContract, XmlWriterDelegator xmlWriter, Object obj, RuntimeTypeHandle declaredTypeHandle) at System.Runtime.Serialization.XmlObjectSerializerWriteContext.SerializeWithoutXsiType(DataContract dataContract, XmlWriterDelegator xmlWriter, Object obj, RuntimeTypeHandle declaredTypeHandle) at System.Runtime.Serialization.DataContractSerializer.InternalWriteObjectContent(XmlWriterDelegator writer, Object graph, DataContractResolver dataContractResolver) at System.Runtime.Serialization.DataContractSerializer.InternalWriteObject(XmlWriterDelegator writer, Object graph, DataContractResolver dataContractResolver) at System.Runtime.Serialization.XmlObjectSerializer.WriteObjectHandleExceptions(XmlWriterDelegator writer, Object graph, DataContractResolver dataContractResolver) at System.Runtime.Serialization.DataContractSerializer.WriteObject(XmlWriter writer, Object graph) at System.Net.Http.Formatting.XmlMediaTypeFormatter.WriteToStream(Type type, Object value, Stream writeStream, HttpContent content) at System.Net.Http.Formatting.XmlMediaTypeFormatter.WriteToStreamAsync(Type type, Object value, Stream writeStream, HttpContent content, TransportContext transportContext, CancellationToken cancellationToken) --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter.GetResult() at System.Web.Http.WebHost.HttpControllerHandler.<WriteBufferedResponseContentAsync>d__1b.MoveNext()
</StackTrace>
</InnerException>
</Error>
Run Code Online (Sandbox Code Playgroud)
问题可能在于您使用的结果,XmlDocument因为我也找不到代码的任何问题.至于为什么我相信这一点
HttpControllerHandler所以它可能与您在何处或如何为您的回复提供服务有关.InvalidOperationException但是它会读取只有在The SqlConnection closed or dropped during a streaming operation. For more information about streaming, see SqlClient Streaming Support.XmlException因此根据您收到的异常,这不会是一个可能的失败点.这是猜测,因为我不知道您正在使用什么框架,或者这是WebApi方法还是在调用堆栈中向下提供结果的方法.
因此,您需要解决的问题是将数据转换为可以通过您使用的任何框架进行序列化的格式.如需更多帮助,请提供.
WebApiConfig.cs文件中配置了正确的格式化程序.GlobalConfiguration.Configuration.Formatters.Add(new System.Net.Http.Formatting.XmlMediaTypeFormatter()); GlobalConfiguration.Configuration.Formatters.XmlFormatter.UseXmlSerializer = true;我可以通过XmlDocument在Web API控制器中返回a 作为响应来复制确切的错误和消息.然后再次说明它与方法的内容无关,但更多的是响应中使用的XmlDocument.如果您直接在响应中返回XmlDocument(因此不是较大对象的一部分),我可以通过添加一个HttpContent知道如何反序列化(提取实际Xml内容)的新类型来修复它XmlDocument.这是基于此前发布的SO答案Darrel Miller.这是一个完整的自包含示例中的修复.
using System.IO;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
using System.Web.Http;
using System.Xml;
namespace WebApiTests.Controllers
{
public class HomeController : ApiController
{
const string sampleData = "<?xml version=\"1.0\"?><catalog><book id=\"bk101\"><author>Gambardella, Matthew</author><title>XML Developer's Guide</title><genre>Computer</genre><price>44.95</price><publish_date>2000-10-01</publish_date><description>An in-depth look at creating applications with XML.</description></book></catalog>";
public HttpResponseMessage Get()
{
var doc = new XmlDocument();
doc.LoadXml(sampleData);
return new HttpResponseMessage()
{
RequestMessage = Request,
Content = new XmlContent(doc)
};
}
}
public class XmlContent : HttpContent
{
private readonly MemoryStream _Stream = new MemoryStream();
public XmlContent(XmlDocument document)
{
document.Save(_Stream);
_Stream.Position = 0;
Headers.ContentType = new MediaTypeHeaderValue("application/xml");
}
protected override Task SerializeToStreamAsync(Stream stream, System.Net.TransportContext context)
{
_Stream.CopyTo(stream);
var tcs = new TaskCompletionSource<object>();
tcs.SetResult(null);
return tcs.Task;
}
protected override bool TryComputeLength(out long length)
{
length = _Stream.Length;
return true;
}
protected override void Dispose(bool disposing)
{
if(_Stream != null)
_Stream.Dispose();
}
}
}
Run Code Online (Sandbox Code Playgroud)
你的方法确实存在一些问题,因为它涉及到SqlConnection.以下是带有解释的清理代码.
public XmlDocument GetPunchListXml(string communityDesc)
{
// 1. Use a new SqlConnection everywhere and do not register SqlConnection as a field on the class.
// This is a Microsoft recommended best practice. Sql Server handles connection pooling so the call new SqlConnection is very cheap.
// 2. a using block will close and dispose the connection for you
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
using (SqlCommand command = new SqlCommand("GetPunchList", connection))
{
command.CommandType = CommandType.StoredProcedure;
SqlParameter parameter1 = new SqlParameter("@communityDesc", SqlDbType.VarChar);
parameter1.Value = communityDesc;
parameter1.Direction = ParameterDirection.Input;
command.Parameters.Add(parameter1);
// wrap your DataReader in a using block
using (var reader = command.ExecuteXmlReader())
{
var doc = new XmlDocument();
if (reader.Read())
{
doc.Load(reader);
}
return doc;
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1807 次 |
| 最近记录: |