从 C# 调用具有复杂输入类型的 WebAPI PUT 方法





5.00/5 (3投票s)
在本文中,我们将学习如何使用模型输入从 C# 调用具有复杂输入类型的 WebAPI PUT 方法
引言
在本文中,我们将学习如何从 C# 调用 WebAPI 的 PUT 方法,该方法接受复杂类型作为输入。
背景
在我学习 WebAPI 的过程中,我发现了很多讲解如何调用 Get 方法的示例,但没有一篇文章能完整地说明如何将复杂输入传递给 PUT/POST 方法,以及如何在服务侧使用 C# 接收和处理这些数据。本文的目的是详细解释这一点。我使用了 .Net Framework 4.0 进行代码演示。本文使用 JSON。
使用代码
今天我将向您展示如何调用 WebAPI 中接受复杂类型作为输入的 PUT 方法。让我们从创建一个空的 WebAPI 项目开始。
创建 WebAPI
我将不再深入介绍如何创建新的 WebAPI。这方面有很多文章。我将我的 WebAPI 项目命名为 TrialWebAPI。
项目创建完成后,添加一个控制器。为此,右键单击 Controllers 文件夹,然后选择 Add -> Controller。这将弹出“Add Controller”对话框。我将我的控制器命名为 Trial。选择如下图所示的模板,然后单击 Add。这将添加控制器。
新添加的控制器将包含默认的 Action 方法:Get
、Put
、Post
和 Delete
。我将只关注 Put
方法。下面是自动生成的 Put
方法的样子。
// PUT api/data/5
public void Put(int id, [FromBody]string value)
{
}
现在是时候创建将作为输入传递给此 Action 方法的复杂类型了。我将创建一个名为 Person 的复杂类型。向 Models 文件夹添加一个类,并将其命名为 person。为该类添加一些属性。这是我的 Person 类版本。
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string FullName { get; set; }
public int Age { get; set; }
}
我们可以通过使用 HttpRequestMessage
或 ModelBinder
来让 PUT 方法接收复杂类型。在本文中,我将演示如何使用 ModelBinder,因为它能保持代码整洁并与我们正在处理的复杂对象相关。我将很快发布一篇关于 HttpRequestMessage
的文章。
为了使用 ModelBinder
,必须实现 IModelBinder
接口。它位于 System.Web.Http.ModelBinding
命名空间下。IModelBinder
定义了一个名为 BindModel 的单一方法。让我们为我们的复杂类型 Person 创建 ModelBinder。
让我们向 Models 文件夹添加一个新类,并将其命名为 PersonModelBinder
。实现 IModelBinder 接口。这是我的 PersonModelBinder 版本。
public class PersonModelBinder : IModelBinder
{
public bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext)
{
if (bindingContext.ModelType != typeof(Person))
{
return false;
}
Person result = JsonConvert.DeserializeObject<Person>
(actionContext.Request.Content.ReadAsStringAsync().Result);
bindingContext.Model = result;
return true;
}
}
代码非常简单且自明。由于这是一个示例,我没有进行太多验证。您可以在此处添加自己的验证逻辑。
注意: HttpActionContext 需要 System.Web.Http.Controllers
命名空间,而 JsonConvert 需要 Newtonsoft.Json
。
完成此操作后,我们必须让 Person 复杂类型知道 PersonModelBinder 将是它的 ModelBinder。这是通过使用 ModelBinder 属性完成的,如下所示。
[ModelBinder(typeof(PersonModelBinder))]
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string FullName { get; set; }
public int Age { get; set; }
}
现在是时候修改 Put 方法以接受 Person 复杂类型作为输入了。Put 方法的新版本如下所示。返回类型已从 void 更改为 HttpResponseMessage
。此方法将 Person 复杂类型作为输入,更新 FullName,然后将 Person 对象发送回。很简单。
// PUT api/data
public HttpResponseMessage Put([ModelBinder]Person putPerson)
{
putPerson.FullName = string.Format("{0},{1}", putPerson.FirstName, putPerson.LastName);
var output = JsonConvert.SerializeObject(putPerson);
StringContent content = new StringContent(output,Encoding.UTF8,"application/json");
HttpResponseMessage message = Request.CreateResponse(HttpStatusCode.OK);
message.Content = content;
return message;
}
我删除了 Id 参数,因为我将不使用它,并且还更改了 URI 以反映这一点。
现在我们的 WebAPI 已准备就绪。我将在控制台应用程序中自行托管该服务以供演示。
为自托管创建控制台应用程序
创建一个控制台应用程序并将其命名为 APIHost。使用 NuGet 并将 Microsoft.AspNet.WebApi.SelfHost
包安装到项目中。安装包后,将以下代码添加到 Program.cs 文件的 Main 方法中。
static void Main(string[] args)
{
HttpSelfHostConfiguration selfConfiguration =
new HttpSelfHostConfiguration("https://:51880/");
selfConfiguration.Routes.MapHttpRoute("API Default","api/{controller}/{id}",
new {id = RouteParameter.Optional});
HttpSelfHostServer selfHostServer = new HttpSelfHostServer(selfConfiguration);
selfHostServer.OpenAsync().Wait();
Console.WriteLine("Press Enter to quit");
Console.ReadLine();
}
服务已自行托管,现在让我们创建一个客户端应用程序来消费该服务。这也将是一个控制台应用程序。
创建客户端以访问 WebAPI
向包含 APIHost 的同一解决方案添加一个新项目,并将此项目命名为 APIClient。使用 NuGet 并将 Microsoft.AspNet.WebApi.Client
包安装到此客户端项目中。在 APIClient 项目中添加对 APIHost 的引用。将 APIClient 设置为启动项目。
注意:有关自托管的完整详细信息,请参阅 Self Hosting。
由于 Put 方法需要 Person 复杂类型作为输入,因此我们必须从客户端发送一个 Person。让我们向 APIClient 添加一个新类,并将其命名为 Person。像在 WebAPI 的 Person 类中一样添加属性。APIClient 中的 Person 类将没有 ModelBinder 属性。
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string FullName { get; set; }
public int Age { get; set; }
}
我们距离调用 Put 方法和显示输出还有一步之遥。将以下代码添加到 APIClient 项目的 Program.cs 中。
class Program
{
static HttpClient client = new HttpClient();
static void Main(string[] args)
{
client.BaseAddress = new Uri("https://:51880");
PutTrial();
Console.ReadLine();
}
private static void PutTrial()
{
Person person = new Person() {FirstName = "Iron", LastName = "Man", Age = 30};
Console.WriteLine("Before calling the PUT method");
Console.WriteLine("-----------------------------");
Console.WriteLine("FirstName of the Person is : {0}", person.FirstName);
Console.WriteLine("LastName of the Person is : {0}", person.LastName);
Console.WriteLine("Fullname of the Person is : {0}", person.FullName);
Console.WriteLine("Age of the Person is : {0}", person.Age);
Console.WriteLine();
string serilized = JsonConvert.SerializeObject(person);
var inputMessage = new HttpRequestMessage
{
Content = new StringContent(serilized,Encoding.UTF8,"application/json")
};
inputMessage.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
HttpResponseMessage message = client.PutAsync("api/trial", inputMessage.Content).Result;
if (message.IsSuccessStatusCode)
{
var inter = message.Content.ReadAsStringAsync();
Person reslutPerson = JsonConvert.DeserializeObject<Person>(inter.Result);
Console.WriteLine("Person returned from PUT method:");
Console.WriteLine("--------------------------------");
Console.WriteLine("FirstName of the Person is : {0}", reslutPerson.FirstName);
Console.WriteLine("LastName of the Person is : {0}", reslutPerson.LastName);
Console.WriteLine("Fullname of the Person is : {0}", reslutPerson.FullName);
Console.WriteLine("Age of the Person is : {0}", reslutPerson.Age);
}
}
}
好了,我们完成了 :)
测试 WebAPI
客户端能够调用服务,因此 TrialWebAPI 必须正在运行。所以先运行 TrialWebAPI 项目。一旦它启动并运行,启动客户端,您就可以看到结果。这是输出的屏幕截图。
关注点
我们学习了如何从 C# 调用 WebAPI 的 PUT 方法,发送复杂类型,并在服务侧接收和处理它。POST 方法可以通过遵循相同的步骤来实现。请在下方分享您的问题或评论。
历史
2015/04/28 - 初始版本