如何通过FromBody将DataTable传递给Web API POST方法(C#)

我从Winforms客户端成功调用Web API应用程序中的POST方法,该客户端传递存储过程的一些参数。

但是,如果可能的话,我希望通过FromBodyfunction将存储过程的结果(我必须首先在客户端上运行)传递给POST方法。

这是通过网络发送的大量数据,但我现在正在这样做的方式我必须运行SP两次 – 首先在客户端Winforms应用程序上,然后在Web API服务器应用程序上,并同时调用此SP似乎有时会引起一些问题。

所以,如果可行,我想通过“FromBody”发送DataTable,或者,如果可取的话,发送数据的XML化或jsonized版本(然后在另一端解压缩,我将其转换为html进行检索)当调用相应的GET方法时。

有人有任何代码可以显示吗?

我可以在这里看到我刚刚通过params的现有代码。

UPDATE

好的,基于Amit Kumar Ghosh的回答,我将我的代码更改为:

WebApiConfig.cs

public static class WebApiConfig { public static void Register(HttpConfiguration config) { // Web API configuration and services // Configure Web API to use only bearer token authentication. config.SuppressDefaultHostAuthentication(); config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType)); // Web API routes config.MapHttpAttributeRoutes(); config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{id}", defaults: new { id = RouteParameter.Optional } ); config.Formatters.Add(new DataTableMediaTypeFormatter()); } public class DataTableMediaTypeFormatter : BufferedMediaTypeFormatter { public DataTableMediaTypeFormatter() : base() { SupportedMediaTypes.Add(new System.Net.Http.Headers.MediaTypeHeaderValue("test/dt")); } public override object ReadFromStream(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger, System.Threading.CancellationToken cancellationToken) { var data = new StreamReader(readStream).ReadToEnd(); var obj = JsonConvert.DeserializeObject(data); return obj; } public override bool CanReadType(Type type) { return true; } public override bool CanWriteType(Type type) { return true; } } 

CONTROLLER

 [Route("{unit}/{begindate}/{enddate}/{stringifiedjsondata}")] [HttpPost] public void Post(string unit, string begindate, string enddate, DataTable stringifiedjsondata) { DataTable dt = stringifiedjsondata; . . . 

客户

 private async Task SaveProduceUsageFileOnServer(string beginMonth, string beginYear, string endMonth, string endYear) { string beginRange = String.Format("{0}{1}", beginYear, beginMonth); string endRange = String.Format("{0}{1}", endYear, endMonth); HttpClient client = new HttpClient(); client.BaseAddress = new Uri("http://localhost:52194"); string dataAsJson = JsonConvert.SerializeObject(_rawAndCalcdDataAmalgamatedList, Formatting.Indented); String uriToCall = String.Format("/api/produceusage/{0}/{1}/{2}/{3}", _unit, beginRange, endRange, @dataAsJson); HttpResponseMessage response = await client.PostAsync(uriToCall, null); } 

……但仍未达到财务主任; 特别是,“DataTable dt = dtPassedAsJson;”中的断点 永远不会到达。

实际上,当一个字符串被传递时,它并没有崩溃,这让我感到惊讶,但那里声明的数据类型是“DataTable”

更新2

我也尝试过这个,在意识到它不是我从客户端传递的字符串化/ jsonized DataTable,而是一个字符串化/ jsonized通用列表:

WEB API控制器

 [Route("{unit}/{begindate}/{enddate}/{stringifiedjsondata}")] [HttpPost] public void Post(string unit, string begindate, string enddate, List stringifiedjsondata) { List _produceUsageList = stringifiedjsondata; 

WebApiConfig.cs

我将此添加到Register方法:

 config.Formatters.Add(new GenericProduceUsageListMediaTypeFormatter()); 

……而这个新课程:

 // adapted from DataTableMediaTypeFormatter above public class GenericProduceUsageListMediaTypeFormatter : BufferedMediaTypeFormatter { public GenericProduceUsageListMediaTypeFormatter() : base() { SupportedMediaTypes.Add(new System.Net.Http.Headers.MediaTypeHeaderValue("test/dt")); } public override object ReadFromStream(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger, System.Threading.CancellationToken cancellationToken) { var data = new StreamReader(readStream).ReadToEnd(); var obj = JsonConvert.DeserializeObject<List>(data); return obj; } public override bool CanReadType(Type type) { return true; } public override bool CanWriteType(Type type) { return true; } } 

尽管如此,控制器中的主要断点线:

 List _produceUsageList = stringifiedjsondata; 

……没达到。

或jsonized版本的数据(然后在另一端解压缩

我结束了这个 –

 public class ParentController : ApiController { public string Post(DataTable id) { return "hello world"; } } 

在配置中

 config.Formatters.Add(new DataTableMediaTypeFormatter()); 

而且 –

 public class DataTableMediaTypeFormatter : BufferedMediaTypeFormatter { public DataTableMediaTypeFormatter() : base() { SupportedMediaTypes.Add(new System.Net.Http.Headers.MediaTypeHeaderValue("test/dt")); } public override object ReadFromStream(Type type, System.IO.Stream readStream, System.Net.Http.HttpContent content, IFormatterLogger formatterLogger, System.Threading.CancellationToken cancellationToken) { var data = new StreamReader(readStream).ReadToEnd(); var obj = JsonConvert.DeserializeObject(data); return obj; } public override bool CanReadType(Type type) { return true; } public override bool CanWriteType(Type type) { return true; } } header of my request - User-Agent: Fiddler Host: localhost:60957 Content-Type : test/dt Content-Length: 28 

身体 –

 [{"Name":"Amit","Age":"27"}] 

我曾经做过一次,虽然代码现在已被取代,所以我只能从我的TFS历史中获得点点滴滴。

从我的控制台应用程序,我将发布数据(是我转换为POCO的DataTable),如下所示;

  using (HttpClient httpClient = new HttpClient()) { MyDataType data = BogusMethodToPopulateData(); httpClient.BaseAddress = new Uri(Properties.Settings.Default.MyService); httpClient.DefaultRequestHeaders.Accept.Clear(); httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); HttpResponseMessage response; // Add reference to System.Net.Http.Formatting.dll response = await httpClient.PostAsJsonAsync("api/revise", data); if (response.IsSuccessStatusCode) { Console.WriteLine("File generation process completed successfully."); } } 

在服务器端,我有以下内容。 这里的概念主要基于链接post的“ 发送复杂类型”部分。 我知道你特意看的是DataTables,但我确信你可以搞乱这些例子或将你的数据提取到POCO中;

  // https://damienbod.wordpress.com/2014/08/22/web-api-2-exploring-parameter-binding/ // http://www.asp.net/web-api/overview/advanced/sending-html-form-data,-part-1 // http://www.asp.net/web-api/overview/formats-and-model-binding/parameter-binding-in-aspnet-web-api [POST("revise")] public IEnumerable Revise(MyDataType data) { if (ModelState.IsValid && data != null) { return ProcessData(data.year, data.period, data.DataToProcess).AsEnumerable(); } return null; } 

客户端实际上以json的forms传递数据表,然后根据特殊媒体类型webapi运行时将json再次转换为服务器上的数据表。

请参阅Hernan Guzman的回答。

基本上,您必须将“[FromBody]”添加到服务器上的方法,然后从客户端传递数据,在URL参数之后添加它。