none
ASP.NET Web API & convert XML to Class RRS feed

  • 問題

  • 我的專案是MVC Web API,需要呼叫另一個SOAP Web Service,會獲得一個XML,將XML轉換成Class會出現錯誤

    這個648地方是如下:應該看起來沒有錯誤才是

    <opdCnt>34</opdCnt>

    GetValue是將XML轉化成Class

    		public static T GetValue<T>(String value)
    		{
    			StringReader strReader = null;
    			XmlSerializer serializer = null;
    			XmlTextReader xmlReader = null;
    
    			Object obj = null;
    			try
    			{
    				strReader = new StringReader(value);
    				serializer = new XmlSerializer(typeof(T));
    				xmlReader = new XmlTextReader(strReader);
    				obj = serializer.Deserialize(xmlReader);
    			}
    			catch (Exception exp)
    			{
    
    			}
    			finally
    			{
    				if (xmlReader != null)
    				{
    					xmlReader.Close();
    				}
    				if (strReader != null)
    				{
    					strReader.Close();
    				}
    			}
    			return (T)Convert.ChangeType(obj, typeof(T));
    		}


    呼叫的函式如下:

    		[HttpPost]
    		public HttpResponseMessage GetRegSchebasicWeb(outsideGetRegSchebasicWeb inputClass)
    		{
    			ServiceReferenceReg1.RegWebsrvServiceClient client = new ServiceReferenceReg1.RegWebsrvServiceClient();
    			ServiceReferenceReg1.resultDTO dto = client.outsideGetRegSchebasicWeb(inputClass.in0, inputClass.in1, inputClass.in2, inputClass.in3, inputClass.in4, inputClass.in5, inputClass.in6);
    
    			System.Xml.XmlNode[] ddd = dto.result as System.Xml.XmlNode[];
    			System.Xml.XmlNode nodeStruct = ddd[1];
    			System.Xml.XmlNode node = ddd[2];
    
    			string structName = nodeStruct.Value.Split(':')[1];
    			structName = structName.Replace("List", "");
    			int number = ddd.Length - 2;
    			string xml = node.InnerXml;
    
    			if (structName == "regSchebasicDAO")
    			{
    				regSchebasicDAO obj = new regSchebasicDAO();
    				obj = GetValue<regSchebasicDAO>("<regSchebasicDAO>" + xml + "</regSchebasicDAO>");
    
    				string yourJson = Newtonsoft.Json.JsonConvert.SerializeObject(obj);
    
    				var response = this.Request.CreateResponse(HttpStatusCode.OK);
    				response.Content = new StringContent(yourJson, Encoding.UTF8, "application/json");
    				return response;
    			}
    			else
    			{
    				return null;
    			}
    		}


    我是寫一個Windows Form去呼叫Web API

    		private static async Task<TO> Get1<T, TO>(T product, string path)
    		{
    			HttpResponseMessage response = await client.PostAsJsonAsync(path, product);
    			response.EnsureSuccessStatusCode();
    			string result = await response.Content.ReadAsStringAsync();
    			TO product2 = Newtonsoft.Json.JsonConvert.DeserializeObject<TO>(result);
    			return product2;
    		}
    
    		async private void buttonoutsideGetRegSchebasic_Click(object sender, EventArgs e)
    		{
    			outsideGetRegSchebasicWeb product = new outsideGetRegSchebasicWeb();
    			product.in0 = "23";
    			product.in1 = DateTime.Now;
    			product.in2 = DateTime.Now.AddDays(5);
    			product.in3 = "";
    			product.in4 = "";
    			product.in5 = "";
    			product.in6 = "";
    
    			var myResult = await Get1<outsideGetRegSchebasicWeb, regSchebasicDAO>(product, "api/outside/GetRegSchebasicWeb");
    
    			Debug.WriteLine("deptName = " + myResult.deptName);
    			Debug.WriteLine("docName = " + myResult.docName);
    			Debug.WriteLine("roomDesc = " + myResult.roomDesc);
    		}

    如果我是用PostMan去呼叫Web API的話,則XML轉class,正常。


    請問一下傳輸大量資料除了Web Service要設定外,Client端(Windows Form)是否也要設定甚麼?為什麼一樣的Web API,在Postman呼叫是可以成功回傳,但是用Windows Form卻是會出現錯誤?


    2020年5月6日 上午 02:57

解答

  • 後來我與同事討論,取代public static T GetValue<T>(String value)
    改用DTO_TO_DS,將resultDTO轉換成DataSet再轉換成Json使用,特定失敗的日期錯誤就沒有了。
    		public static DataSet DTO_To_DS(dynamic DTO)
    		{
    			DataSet DS = new DataSet();
    			int cnt = 0;
    			for (int i = 2; i < DTO.result.Length; i++)
    			{
    				System.IO.StringReader reader = new System.IO.StringReader(DTO.result[i].OuterXml);
    				DataSet DS2 = new DataSet();
    				DS2.ReadXml(reader);
    				if (cnt == 0)
    				{
    					DS = DS2.Copy();
    				}
    				else
    				{
    					DS.Tables[0].ImportRow(DS2.Tables[0].Rows[0]);
    				}
    				cnt += 1;
    			}
    			return DS;
    		}
    		[HttpPost]
    		public HttpResponseMessage GetReg(outsideGetReg inputClass)
    		{
    			ServiceReferenceReg1.RegWebsrvServiceClient client = new ServiceReferenceReg1.RegWebsrvServiceClient();
    			ServiceReferenceReg1.resultDTO dto = client.GetReg(inputClass.in0, inputClass.in1, inputClass.in2, inputClass.in3, inputClass.in4, inputClass.in5, inputClass.in6);
    
    			DataSet ds = DTO_To_DS(dto);
    			string yourJson = Newtonsoft.Json.JsonConvert.SerializeObject(ds);
    
    			var response = this.Request.CreateResponse(HttpStatusCode.OK);
    			response.Content = new StringContent(yourJson, Encoding.UTF8, "application/json");
    			return response;



    • 已標示為解答 akira32 2020年5月11日 上午 02:00
    2020年5月11日 上午 02:00

所有回覆

  • 如果是呼叫WCF服務, Client是要設定的, 而且要設定給正確的Binding, 如果Postman又能成功, 腦袋就打結了...

    這可能要試看看, 讓Web API直接傳回寫死的資料, 而不是呼叫Soap Web Service的結果, 看Windows Forms Client是否能夠執行成功, 以縮小可能引發錯誤的原因

    2020年5月6日 上午 06:11
  • 後來我與同事討論,取代public static T GetValue<T>(String value)
    改用DTO_TO_DS,將resultDTO轉換成DataSet再轉換成Json使用,特定失敗的日期錯誤就沒有了。
    		public static DataSet DTO_To_DS(dynamic DTO)
    		{
    			DataSet DS = new DataSet();
    			int cnt = 0;
    			for (int i = 2; i < DTO.result.Length; i++)
    			{
    				System.IO.StringReader reader = new System.IO.StringReader(DTO.result[i].OuterXml);
    				DataSet DS2 = new DataSet();
    				DS2.ReadXml(reader);
    				if (cnt == 0)
    				{
    					DS = DS2.Copy();
    				}
    				else
    				{
    					DS.Tables[0].ImportRow(DS2.Tables[0].Rows[0]);
    				}
    				cnt += 1;
    			}
    			return DS;
    		}
    		[HttpPost]
    		public HttpResponseMessage GetReg(outsideGetReg inputClass)
    		{
    			ServiceReferenceReg1.RegWebsrvServiceClient client = new ServiceReferenceReg1.RegWebsrvServiceClient();
    			ServiceReferenceReg1.resultDTO dto = client.GetReg(inputClass.in0, inputClass.in1, inputClass.in2, inputClass.in3, inputClass.in4, inputClass.in5, inputClass.in6);
    
    			DataSet ds = DTO_To_DS(dto);
    			string yourJson = Newtonsoft.Json.JsonConvert.SerializeObject(ds);
    
    			var response = this.Request.CreateResponse(HttpStatusCode.OK);
    			response.Content = new StringContent(yourJson, Encoding.UTF8, "application/json");
    			return response;



    • 已標示為解答 akira32 2020年5月11日 上午 02:00
    2020年5月11日 上午 02:00