[英]Why do i get this error while calling a web service that a circular reference was detected while serializing an object of type?
I am using an asmx webservice in aspx page.我在 aspx 页面中使用 asmx 网络服务。 I am calling it but it throws this error.我正在调用它,但它会引发此错误。
A circular reference was detected while serializing an object of type SAPWebServices.clsFunctionalLocation.序列化 SAPWebServices.clsFunctionalLocation 类型的 object 时检测到循环引用。
I have used web services before but this one really giving me hard time.我以前使用过 web 服务,但这确实让我很难受。 What is the problem?问题是什么? Why it does so?为什么会这样?
click event:点击事件:
protected void btnAdd_Click(object sender, EventArgs e)
{
SAPWebServicesSoapClient c = new SAPWebServicesSoapClient("SAPWebServicesSoap");
List<clsFunctionalLocation> ListFuncLocations = new List<clsFunctionalLocation>();
SAPWebServices.clsFunctionalLocation objFunLocation = new SAPWebServices.clsFunctionalLocation();
for(int i=1; i<=Convert.ToInt32(txtBoxRecords.Text); i++)
{
objFunLocation.Description = txtDes.Text;
objFunLocation.EquipmentCategory = txtEqCat.Text;
objFunLocation.EquipmentNo = txtEqNo.Text + txtBoxRecords.Text;
objFunLocation.EquipmentType = txtEqNo.Text + txtBoxRecords.Text;
objFunLocation.FunctionalLocation = txtFL.Text;
ListFuncLocations.Add(objFunLocation);
}
objFunLocation.ListFunctionalLocations = ListFuncLocations.ToArray();
c.SendFunctionalLocations(objFunLocation);
}
Web Method: Web 方法:
[WebMethod]
public clsFunctionalLocsResponse SendFunctionalLocations(clsFunctionalLocation Send_ObjFunctionalLocation) {
clsFunctionalLocation ObjFunctionalLocations = new clsFunctionalLocation();
return ObjFunctionalLocations.InsertFunctionalLocationsSAP(Send_ObjFunctionalLocation);
}
DAL:达尔:
namespace SAPServicesCollection
{
public class clsFunctionalLocation
{
public string Description { get; set; }
public string FunctionalLocation { get; set; }
public string EquipmentNo { get; set; }
public string EquipmentCategory { get; set; }
public string EquipmentType { get; set; }
public List<clsFunctionalLocation> ListFunctionalLocations { get; set; }
public clsFunctionalLocation()
{
}
public clsFunctionalLocsResponse InsertFunctionalLocationsSAP(clsFunctionalLocation Param_ObjFunctionalLocations)
{
try
{
string query = "InsertFunctionalLocationsSAP";
string ConnectionString = System.Configuration.ConfigurationManager.ConnectionStrings["SAPConnection"].ConnectionString;
clsFunctionalLocsResponse ObjFunctionalLocsResponse = new clsFunctionalLocsResponse();
ObjFunctionalLocsResponse.StatusRet = "";
using (SqlConnection cn = new SqlConnection(ConnectionString))
using (SqlCommand cmd = new SqlCommand(query, cn))
{
cmd.CommandType = CommandType.StoredProcedure;
if (ListFunctionalLocations.Count > 0)
{
foreach (var traverser in Param_ObjFunctionalLocations.ListFunctionalLocations)
{
cmd.Parameters.Add("@Description", SqlDbType.VarChar, 1000).Value = traverser.Description;
cmd.Parameters.Add("@FunctionalLocation", SqlDbType.VarChar, 20).Value = traverser.FunctionalLocation;
cmd.Parameters.Add("@EquipmentNo", SqlDbType.VarChar, 20).Value = traverser.EquipmentNo;
cmd.Parameters.Add("@EquipmentCategory", SqlDbType.VarChar, 20).Value = traverser.EquipmentCategory;
cmd.Parameters.Add("@EquipmentType", SqlDbType.VarChar, 20).Value = traverser.EquipmentType;
cmd.Parameters.Add("@StatusRet", SqlDbType.VarChar, 20).Direction = ParameterDirection.Output;
cmd.Parameters.Add("@ErrorRet", SqlDbType.VarChar, 100).Direction = ParameterDirection.Output;
cn.Open();
cmd.ExecuteNonQuery();
ObjFunctionalLocsResponse.StatusRet = Convert.ToString(cmd.Parameters["@StatusRet"].Value);
ObjFunctionalLocsResponse.ErrorRet = Convert.ToString(cmd.Parameters["@ErrorRet"].Value);
cmd.Parameters.Clear();
cn.Close();
}
}
else
{
ObjFunctionalLocsResponse.StatusRet = "Failed";
ObjFunctionalLocsResponse.ErrorRet = "No data has been provided";
}
}
return ObjFunctionalLocsResponse;
}
catch (Exception ex)
{
throw ex;
}
}
}
public class clsFunctionalLocsResponse
{
public string StatusRet { get; set; }
public string ErrorRet { get; set; }
public clsFunctionalLocsResponse()
{
}
}
}
In your class clsFunctionalLocation
you have a list of the same type ( List<clsFunctionalLocation>
), that wont work out when serializing.在您的 class clsFunctionalLocation
中,您有一个相同类型的列表( List<clsFunctionalLocation>
),在序列化时不会起作用。 In general you can say if you could make a struct
out of it it will serialize, in your case it wont because you are refering to the object from itself which is called a "curcular reference".一般来说,你可以说如果你可以用它制作一个struct
,它会序列化,在你的情况下它不会,因为你从本身引用 object ,这被称为“curcular reference”。
To avoid misstakes like this you should only serialize structs
not classes, that way you are on the safe side.为了避免这样的错误,你应该只序列化structs
而不是类,这样你就安全了。
Here is what I changed:这是我所做的更改:
InsertFunctionalLocationsSAP
to the appropriate name AppendFunctionalLocationsSAP
.将InsertFunctionalLocationsSAP
重命名为适当的名称AppendFunctionalLocationsSAP
。AppendFunctionalLocationsSAP
.简化了AppendFunctionalLocationsSAP
的参数。var
where appropriate.在适当的地方用var
替换了显式类型声明。FucntionalLocation
and FunctionalLocsResponse
to structs from classes.将FucntionalLocation
和FunctionalLocsResponse
从类移至结构。Here is how your Structures could look like这是您的结构的外观
public struct FunctionalLocation
{
public string Description {get; set;}
public string FunctionalLocation {get; set;}
public string EquipmentNo { get; set; }
public string EquipmentCategory { get; set; }
public string EquipmentType { get; set; }
}
public struct FunctionalLocsResponse
{
public string StatusRet {get; set;}
public string ErrorRet {get; set;}
}
public class FunctionalLocationCollection
{
public string Description {get; set;}
public string FunctionalLocation {get; set;}
public string EquipmentNo { get; set; }
public string EquipmentCategory { get; set; }
public string EquipmentType { get; set; }
public List<FunctionalLocation> ListFunctionalLocations {get; set;}
public FunctionalLocsResponse AppendFunctionalLocationsSAP(List<FunctionalLocation> locationCollection)
{
var query = "InsertFunctionalLocationsSAP";
var locsResponse = new clsFunctionalLocsResponse();
locsResponse.StatusRet = "";
string ConnectionString = System.Configuration.ConfigurationManager.ConnectionStrings["SAPConnection"].ConnectionString;
using var cn = new SqlConnection(ConnectionString)
using var cmd = new SqlCommand(query, cn)
cmd.CommandType = CommandType.StoredProcedure;
if (ListFunctionalLocations.Count > 0)
{
foreach (var item in locationCollection)
{
cmd.Parameters.Add("@Description", SqlDbType.VarChar, 1000).Value = item.Description;
cmd.Parameters.Add("@FunctionalLocation", SqlDbType.VarChar, 20).Value = item.FunctionalLocation;
cmd.Parameters.Add("@EquipmentNo", SqlDbType.VarChar, 20).Value = item.EquipmentNo;
cmd.Parameters.Add("@EquipmentCategory", SqlDbType.VarChar, 20).Value = item.EquipmentCategory;
cmd.Parameters.Add("@EquipmentType", SqlDbType.VarChar, 20).Value = item.EquipmentType;
cmd.Parameters.Add("@StatusRet", SqlDbType.VarChar, 20).Direction = ParameterDirection.Output;
cmd.Parameters.Add("@ErrorRet", SqlDbType.VarChar, 100).Direction = ParameterDirection.Output;
cn.Open();
cmd.ExecuteNonQuery();
locsResponse.StatusRet = Convert.ToString(cmd.Parameters["@StatusRet"].Value);
locsResponse.ErrorRet = Convert.ToString(cmd.Parameters["@ErrorRet"].Value);
cmd.Parameters.Clear();
cn.Close();
}
}
else
{
locsResponse.StatusRet = "Failed";
locsResponse.ErrorRet = "No data has been provided";
}
return locsResponse;
}
}
If you still need recursive nesting I advice a Child and Collection of FunctionalLocation
, both classes.如果您仍然需要递归嵌套,我建议使用 Child 和 Collection of FunctionalLocation
,这两个类。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.