【发布时间】:2021-09-08 16:14:59
【问题描述】:
我无法使用 HttpClient 对象从 WPF 应用程序执行发布或删除操作。 但我可以使用 HttpClient 进行 Get 和 GetById(string id) 操作。
HttpClient 的命名空间是 System.Net.Http。 [我尝试使用 Windows.Web.Http.HttpClient,但我无法将此 dll 添加为 WPF 项目中的引用。此 httpclient dll 必须从 Internet 下载。]
这是删除操作的代码。以下代码在 WPF 按钮的点击事件处理程序中。
public void DeleteByID(string id)
{
HttpClient client = new HttpClient(); //system.net.http
client.BaseAddress = new Uri("http://localhost:44390/");
var url = "api/Player/" + id;
HttpResponseMessage response = client.DeleteAsync(url).Result; **// ERROR here**
response.EnsureSuccessStatusCode();
if (response.IsSuccessStatusCode)
{
MessageBox.Show("User Deleted");
}
else
{
MessageBox.Show("Error Code");
}
}
其对应的Web Api HttpDelete方法如下图:
public class PlayerController : ApiController
{
SqlConnection con = new
SqlConnection(ConfigurationManager.ConnectionStrings["dbconnection"].ToString());
SqlCommand cmd = new SqlCommand();
SqlDataAdapter adp = null;
[HttpDelete]
public bool DeleteByID(string id)
{
bool isdeleted = false;
try
{
cmd.CommandType = CommandType.Text;
cmd.CommandText = "delete from tbl_Player where ID = '" + id + "'";
cmd.Connection = con;
if (con.State == ConnectionState.Open)
{
con.Close();
}
int res = cmd.ExecuteNonQuery();
if (res > 0)
{
isdeleted = true;
}
else
{
isdeleted = false;
}
con.Close();
return isdeleted;
}
catch
{
return isdeleted;
}
}
[HttpGet]
public DataTable Get()
{
DataTable dt = new DataTable();
try
{
cmd.CommandType = CommandType.Text;
cmd.CommandText = "select * from tbl_Player";
cmd.Connection = con;
if (con.State == ConnectionState.Open)
{
con.Close();
}
adp = new SqlDataAdapter(cmd);
dt.TableName = "tbl_Player";
adp.Fill(dt);
con.Close();
}
catch
{
}
return dt;
}
}
我的 Player 类如下所示:
public class Player
{
public int ID { get; set; }
public string Name { get; set; }
public int Age { get; set; }
public string Place { get; set; }
public string Country { get; set; }
public bool IsActive { get; set; }
}
在SQLServer中,表定义如下图。
CREATE TABLE [dbo].[tbl_Player](
[ID] [int] IDENTITY(1,1) NOT NULL,
[Name] [varchar](50) NULL,
[Age] [int] NULL,
[Place] [varchar](50) NULL,
[Country] [varchar](50) NULL,
[IsActive] [bit] NULL,
CONSTRAINT [PK_tbl_Player] PRIMARY KEY CLUSTERED
下面是 Get 操作的工作代码,上面的控制器类中提到了它的 web api 方法。
public void GetData()
{
HttpClient client = new HttpClient();
client.BaseAddress = new Uri("https://localhost:44390/");
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
HttpResponseMessage response = client.GetAsync("api/Player").Result;
response.EnsureSuccessStatusCode();
if (response.IsSuccessStatusCode)
{
var players = response.Content.ReadAsAsync<IEnumerable<Player>>().Result;
dgPlayers.ItemsSource = players; // dgPlayers is the datagrid in WPF Window.
}
else
{
MessageBox.Show("Error Code");
}
}
实际上,我遇到了 4 种错误。错误的详细信息如下:
System.AggregateException: '发生一个或多个错误。'
错误1:HttpRequestException:发送请求时发生错误。
错误号 2:WebException:底层连接已关闭:接收时发生意外错误。
Error No.3 : IOException: Unable to read data from the transport connection: 一个现有的连接被远程主机强行关闭。
错误号 4 : SocketException: 现有连接被远程主机强行关闭
我尝试了所有方法来解决它。我也使用了异步和等待。当我使用 async 和 await 时,没有抛出错误,它被卡在那里 - UI 变得没有响应。 DeleteById 方法中抛出错误。调用没有来到 web api 删除 web 方法。
请帮我解决这个问题。
谢谢
【问题讨论】:
-
你能显示控制器动作吗?
-
@Serge 更新了问题。谢谢。
-
不要阻止异步调用。使
DeleteByID异步并使用await client.DeleteAsync(url);。发布实际的、完整的异常文本,而不仅仅是其中的一部分。您发布的部分表明 服务器 崩溃了。 -
服务器操作很容易受到 SQL 注入攻击。如果
ID包含例如1'; drop table tbl;-,您的代码将删除该表。catch将隐藏之后发生的任何错误。服务器崩溃的事实表明在该操作之前引发了异常,可能在控制器的构造函数中。您应该添加适当的异常处理和日志记录而不是隐藏错误,否则几乎不可能发现问题 -
@Serge 我已经详细阐述了这个问题。请看一下。
标签: c# asp.net-web-api