创建接受从参数类型(多态参数)派生的任何类型的参数的操作
To Create Action That Accepts a Parameter Of Any Type Derived From The Parameter Type (Polymorphic Parameter)
我想构建一个动态结构,供客户端在 Web 中询问服务器 API。我曾尝试使用以下代码来处理我的问题,但是,它不起作用。
- How can I send a generic type like
<travel>
to service
- How can I change server code (or all need to change client/server)?
PS:如果您看完我的问题,谢谢您的耐心等待。
客户代码
var serializer = new JavaScriptSerializer();
var product = new travel() { travel_desc = "select * from travel" };
var jsonText = serializer.Serialize(product);
var client = new HttpClient();
client.BaseAddress = new Uri("http://localhost:65370/");
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
StringContent content = new StringContent(jsonText, Encoding.UTF8, "application/json");
var z = client.PostAsync<travel>("api/bb", product, new JsonMediaTypeFormatter()).Result;
服务器代码,无效
public IHttpActionResult Post< T > (Object x) where T : new()
{
........................
}
顺便说一句,没关系,但我不知道如何将 发送到服务器
public IHttpActionResult Post(Object x)
{
........................
}
错误信息
Client call server, server will be getting an error message " StatusCode: 404, ReasonPhrase: 'Not Found' "
var z = client.PostAsync < travel > ("api/dd", product, new JsonMediaTypeFormatter()).Result; <--client
public class ddController< T > : ApiController {public virtual void Post() { ... } } <---server
// sorry all , my English isn't very well , so I will try to use code to tell everyone how i want
// in format situations,I will create 2 controller when I have 2 models(ex: users/product) , as following (client)
var a = client.PostAsync("api/users", users, new JsonMediaTypeFormatter()).Result;
var b = client.PostAsync("api/product", product, new JsonMediaTypeFormatter()).Result;
//and then when the users and product controllers was created the post code should be like as following (server)
public IHttpActionResult Postusers(users travel) {}
public IHttpActionResult Postproduct(product travel) {}
//now i just want to create 1 controller for above like as follwing
var b = client.PostAsync<users/product>("api/all", product, new JsonMediaTypeFormatter()).Result;(client)
public IHttpActionResult Post<T>(Object ForAll) where T : new() {} (server)
JSON.NET,Web API JSON 序列化程序,能够在序列化对象时发送类型信息,并使用相同的信息对其进行反序列化。
它使用的技巧是包含一个 $type
属性 作为 JSON 对象的第一个 属性。
如果你想使用这个技术,你需要有一个基础class或者一个接口,例如ITravel
,从它继承所有可能的classes,并且使用基础 class 或接口作为参数类型,像这样:
public interface ITravel
{
public int TravelId { get; set; }
}
public class TravelTypeA : ITravel
{
public int TravelId { get; set; }
public string Destination { get; set; }
}
public class TravelTypeB : ITravel
{
...
}
[HttpPost]
public object PostMeATravel(ITravel travel)
{
// check what type is travel with "is" or ".GetType()"
}
您还需要指示 JSON 在(反)序列化 ITravel
对象时包含类型信息。 (JSON TypeName Handling):
JsonSerializerSettings serializerSettings
= GlobalConfiguration.Configuration.Formatters
.JsonFormatter.SerializerSettings;
serializerSettings.TypeNameHandling = TypeNameHandling.Auto;
然后你必须 post 一个带有 typeInformation 的 JSON,像这样:
{
$type: 'SampleApp.TravelTypeA, SampleApp',
TravelId: 22,
Destination: 'La Almunia de Doña Godina'
}
当您这样做时,JSON.NET 将使用类型信息创建一个 TravelTypeA
对象,并将其作为参数传递给需要 ITravel
的操作。如果需要,您可以在操作中检查接收到的参数的类型,如下所示:if (travel.GetType().Name == "TravelTypeA") { ... }
查看此问答,了解有关如何执行此操作、其工作原理、此方法的优缺点以及替代方法的更多信息:Deserialising Json to derived types in Asp.Net Web API
注意:您可以使用优秀的 Postman 补充 Chrome 来测试 Web API 方法
我想构建一个动态结构,供客户端在 Web 中询问服务器 API。我曾尝试使用以下代码来处理我的问题,但是,它不起作用。
- How can I send a generic type like
<travel>
to service- How can I change server code (or all need to change client/server)?
PS:如果您看完我的问题,谢谢您的耐心等待。
客户代码
var serializer = new JavaScriptSerializer();
var product = new travel() { travel_desc = "select * from travel" };
var jsonText = serializer.Serialize(product);
var client = new HttpClient();
client.BaseAddress = new Uri("http://localhost:65370/");
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
StringContent content = new StringContent(jsonText, Encoding.UTF8, "application/json");
var z = client.PostAsync<travel>("api/bb", product, new JsonMediaTypeFormatter()).Result;
服务器代码,无效
public IHttpActionResult Post< T > (Object x) where T : new()
{
........................
}
顺便说一句,没关系,但我不知道如何将
public IHttpActionResult Post(Object x)
{
........................
}
错误信息
Client call server, server will be getting an error message " StatusCode: 404, ReasonPhrase: 'Not Found' "
var z = client.PostAsync < travel > ("api/dd", product, new JsonMediaTypeFormatter()).Result; <--client
public class ddController< T > : ApiController {public virtual void Post() { ... } } <---server
// sorry all , my English isn't very well , so I will try to use code to tell everyone how i want
// in format situations,I will create 2 controller when I have 2 models(ex: users/product) , as following (client)
var a = client.PostAsync("api/users", users, new JsonMediaTypeFormatter()).Result;
var b = client.PostAsync("api/product", product, new JsonMediaTypeFormatter()).Result;
//and then when the users and product controllers was created the post code should be like as following (server)
public IHttpActionResult Postusers(users travel) {}
public IHttpActionResult Postproduct(product travel) {}
//now i just want to create 1 controller for above like as follwing
var b = client.PostAsync<users/product>("api/all", product, new JsonMediaTypeFormatter()).Result;(client)
public IHttpActionResult Post<T>(Object ForAll) where T : new() {} (server)
JSON.NET,Web API JSON 序列化程序,能够在序列化对象时发送类型信息,并使用相同的信息对其进行反序列化。
它使用的技巧是包含一个 $type
属性 作为 JSON 对象的第一个 属性。
如果你想使用这个技术,你需要有一个基础class或者一个接口,例如ITravel
,从它继承所有可能的classes,并且使用基础 class 或接口作为参数类型,像这样:
public interface ITravel
{
public int TravelId { get; set; }
}
public class TravelTypeA : ITravel
{
public int TravelId { get; set; }
public string Destination { get; set; }
}
public class TravelTypeB : ITravel
{
...
}
[HttpPost]
public object PostMeATravel(ITravel travel)
{
// check what type is travel with "is" or ".GetType()"
}
您还需要指示 JSON 在(反)序列化 ITravel
对象时包含类型信息。 (JSON TypeName Handling):
JsonSerializerSettings serializerSettings
= GlobalConfiguration.Configuration.Formatters
.JsonFormatter.SerializerSettings;
serializerSettings.TypeNameHandling = TypeNameHandling.Auto;
然后你必须 post 一个带有 typeInformation 的 JSON,像这样:
{
$type: 'SampleApp.TravelTypeA, SampleApp',
TravelId: 22,
Destination: 'La Almunia de Doña Godina'
}
当您这样做时,JSON.NET 将使用类型信息创建一个 TravelTypeA
对象,并将其作为参数传递给需要 ITravel
的操作。如果需要,您可以在操作中检查接收到的参数的类型,如下所示:if (travel.GetType().Name == "TravelTypeA") { ... }
查看此问答,了解有关如何执行此操作、其工作原理、此方法的优缺点以及替代方法的更多信息:Deserialising Json to derived types in Asp.Net Web API
注意:您可以使用优秀的 Postman 补充 Chrome 来测试 Web API 方法