我正在编写一个C#表单应用程序来将一些数据发布到Web服务。发布的对象已正确添加到数据库中,但客户端未收到SuccessStatusCode
true
。
这是webservice函数:
[Route("Postitem")]
[ResponseType(typeof(Item))]
public async Task<IHttpActionResult> PostItem(Item item)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
db.items.Add(item);
await db.SaveChangesAsync();
var data = CreatedAtRoute("DefaultApi", new { id = item.Id }, item);
return data;
}
以下是客户端PostItem
功能:
public async Task PostItem()
{
var item = new Item(1, 0, "Posted Item Name 6", "Posted Item Data");
using (var client = new HttpClient())
{
client.BaseAddress = new Uri(baseAddress);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var response = await client.PostAsJsonAsync("api/Postitem", item);
if (response.IsSuccessStatusCode)
{
}
}
}
response.IsSuccessStatusCode
的值为false
。
以下是响应的字符串值:
“StatusCode:500,ReasonPhrase:'内部服务器错误',版本:1.1, 内容:System.Net.Http.StreamContent,Headers:\ r \ n {\ r \ n Pragma: no-cache \ r \ n缓存控制:无缓存\ r \ n日期:星期二,2016年1月26日 03:37:09 GMT \ r \ n服务器:Microsoft-IIS / 10.0 \ r \ n X-AspNet-版本: 4.0.30319 \ r \ n X-Powered-By:ASP.NET \ r \ n Content-Length:1174 \ r \ n Content-Type:application / json; charset = utf-8 \ r \ n到期:-1 \ r \ n}“
客户如何正确判断对象是否正确发布?
答案 0 :(得分:2)
使用消除过程...如果一个语句成功,但该方法在此之后没有返回,那么它可能是什么?我猜你的CreatedAtRoute因为你的项目被添加到你的数据库而抛出了500,但该方法没有成功执行。
或许按this回答建议并尝试:
var data = CreatedAtRoute("DefaultApi", new { controller = "controllername", id = item.Id }, item);
return data;
显然,将"controllername"
替换为控制器的名称。 然而路由属性不能很好地与整个"DefaultApi"
事物互动,因为我相信它们是在不同的路由名称下添加的。您实际上可能想尝试this之类的内容,并为Name
添加RouteAttribute
属性。这将创建一个明确的routeName
,您可以在CreatedAtRoute
中将其用作第一个参数。
CreatedAtRoute
。此功能旨在促进RESTful服务。您的服务并不宁静。您应该改名您的路由"item"
并且具有相同路由的相应GetItem
方法。其中一个接受HTTP POST(您的PostItem),一个接受HTTP GET。CreatedAtRoute
旨在帮助调用函数知道它应调用的URL以便
如果你不想走这条宁静的路线,你可以完全抛弃CreatedAtRoute
而只是这样做:
[Route("Postitem")]
[ResponseType(typeof(Item))]
public async Task<IHttpActionResult> PostItem(Item item)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
db.items.Add(item);
await db.SaveChangesAsync();
return this.Ok(new { id = item.Id });
}
常规调试说明
如果您实际查看控制器的响应,您可能自己可以解决此问题。使用this或this之类的内容。您发布的消息称其长度为1174字节。你想打赌它包含一个JSON格式的异常,它会告诉你究竟出了什么问题?
一般API说明
我注意到您直接传递实体(将item
直接添加到数据库中)。这非常糟糕,尤其是导航属性(它们会在序列化程序中导致无限循环)。我建议你的API和数据库有一个单独的模型。使您的方法能够将自身转换为数据库项,反之亦然。
编辑:阅读JSON的示例
首先,在某个地方声明一个如下所示的类:
[DataContract] //found in System.Runtime.Serializatino
public class ItemResult
{
[DataMember(Name = "id")] //Same place as DataContractAttribute
public int Id { get; set; }
}
此类表示来自您服务的响应。接下来,在您的客户端类(您声明PostItem
的位置...而不是操作方法,客户端方法)中,声明以下内容:
private static readonly JsonSerializer serializer = new JsonSerializer();
这是来自非常受欢迎的JSON.Net库。如果您还没有安装,请通过nuget安装。
接下来,这是你的PostItem需要的样子:
public async Task<ItemResult> PostItem()
{
var item = new Item(1, 0, "Posted Item Name 6", "Posted Item Data");
using (var client = new HttpClient())
{
client.BaseAddress = new Uri(baseAddress);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
using (var response = await client.PostAsJsonAsync("api/Postitem", item))
using (var rs = await response.Content.ReadAsStreamAsync())
using (var sr = new StreamRead(rs))
using (var jr = new JsonTextReader(sr))
{
if (response.IsSuccessStatusCode)
{
return serializer.Deserialize<ItemResult>(jr);
}
else
{
//deserialize as something else...an error message perhaps?
}
}
}
}
以下是对所发生情况的解释:
response.Content.ReadAsStreamAsync
。response.EnsureSuccessStatusCode
。serializer
对象将服务器返回的JSON对象反序列化为ItemResponse
类。