C# 为什么我在调用一个web服务时遇到这个错误,即序列化类型的对象时检测到循环引用?

C# 为什么我在调用一个web服务时遇到这个错误,即序列化类型的对象时检测到循环引用?,c#,asp.net,web-services,webforms,asmx,C#,Asp.net,Web Services,Webforms,Asmx,我正在aspx页面中使用ASMXWebService。我正在调用它,但它抛出了这个错误 序列化SAPWebServices.clsFunctionalLocation类型的对象时检测到循环引用。 我以前使用过web服务,但这一次真的让我很为难。有什么问题?为什么会这样 单击事件: protected void btnAdd_Click(object sender, EventArgs e) { SAPWebServicesSoapClient c = new SAPWeb

我正在aspx页面中使用ASMXWebService。我正在调用它,但它抛出了这个错误

序列化SAPWebServices.clsFunctionalLocation类型的对象时检测到循环引用。

我以前使用过web服务,但这一次真的让我很为难。有什么问题?为什么会这样

单击事件:

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);
    }
达尔:

命名空间SAPServicesCollection
{
公共类clsFunctionalLocation
{
公共字符串说明{get;set;}
公共字符串函数分配{get;set;}
公共字符串设备no{get;set;}
公共字符串设备类别{get;set;}
公共字符串设备类型{get;set;}
公共列表ListFunctionalLocations{get;set;}
公共clsFunctionalLocation()
{
}
公共CLSFunctionAllocResponse InsertFunctionalLocationsSAP(clsFunctionalLocation参数_ObjFunctionalLocations)
{
尝试
{
string query=“InsertFunctionalLocationsSAP”;
string ConnectionString=System.Configuration.ConfigurationManager.ConnectionString[“SAPConnection”].ConnectionString;
CLSFunctionAllocResponse OBJFunctionAllocResponse=新的CLSFunctionAllocResponse();
ObjFunctionalLocsResponse.StatusRet=“”;
使用(SqlConnection cn=newsqlconnection(ConnectionString))
使用(SqlCommand cmd=newsqlcommand(query,cn))
{
cmd.CommandType=CommandType.storedProcess;
如果(ListFunctionalLocations.Count>0)
{
foreach(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();
}
}
其他的
{
ObjFunctionalLocsResponse.StatusRet=“失败”;
ObjFunctionalLocsResponse.ErrorRet=“未提供任何数据”;
}
}
返回ObjFunctionalLocsResponse;
}
捕获(例外情况除外)
{
掷骰子;
}
}
}
公共类clsFunctionalLocsResponse
{
公共字符串StatusRet{get;set;}
公共字符串ErrorRet{get;set;}
公共clsFunctionalLocsResponse()
{
}
}
}

在您的类中
clsFunctionalLocation
您有一个相同类型的列表(
list
),在序列化时无法运行。一般来说,你可以说,如果你能用它来构造一个
struct
,它将被序列化,在你的例子中,它不会,因为你是从对象本身引用它,它被称为“curcular引用”

为了避免这样的错误,您应该只序列化
structs
而不是类,这样您就安全了

以下是我所改变的:

  • 因为在循环中不使用递归嵌套,所以我删除了它们
  • 修复了命名约定冲突
  • insertfunctionallocationsap
    重命名为相应的名称
    appendfunctionallocationsap
  • 简化了
    AppendFunctionalLocationsSAP
    的参数
  • 在适当的情况下,将显式类型声明替换为
    var
  • FUNCTIONALLOCATION
    FunctionalLocsResponse
    从类移动到结构
  • 使用简化的语句
  • 删除无用的尝试捕捉
以下是您的结构的外观

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;
   }
}
公共结构函数分配
{
公共字符串说明{get;set;}
公共字符串函数分配{get;set;}
公共字符串设备no{get;set;}
公共字符串设备类别{get;set;}
公共字符串设备类型{get;set;}
}
公共结构函数响应
{
公共字符串StatusRet{get;set;}
公共字符串ErrorRet{get;set;}
}
公共类函数分配集合
{
公共字符串说明{get;set;}
公共字符串函数分配{get;set;}
公共字符串设备no{get;set;}
公共字符串设备类别{get;set;}
公共字符串设备类型{get;set;}
公共列表ListFunctionalLocations{get;set;}
public FunctionAllocResponse AppendFunctionalLocationsSAP(列表位置集合)
{
var query=“InsertFunctionalLocationsSAP”;
var locsResponse=新的clsFunctionalLocsResponse();
本地响应
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()
        {


        }
    }
}
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;
   }
}