【发布时间】:2013-09-13 06:53:46
【问题描述】:
我对 Web Api 比较陌生,并且在发布 Person 对象时遇到了麻烦。如果我在调试中运行,我会看到我的 uriString 永远不会被设置,我不明白为什么。因此,我在 Fiddler 中针对所有尝试的帖子收到“400 Bad Request”错误。
我尝试复制其他人在 Post 操作方面所做的事情。我发现的每个示例都使用存储库将人员添加到数据库中。但是,我没有存储库,而是使用 NHibernate Save 方法来执行此功能。下面是域类,按代码文件映射,WebApiConfig,PersonController。
public class Person
{
public Person() { }
[Required]
public virtual string Initials { get; set; }
public virtual string FirstName { get; set; }
public virtual char MiddleInitial { get; set; }
public virtual string LastName { get; set; }
}
public class PersonMap : ClassMapping<Person>
{
public PersonMap()
{
Table("PERSON");
Lazy(false);
Id(x => x.Initials, map => map.Column("INITIALS"));
Property(x => x.FirstName, map => map.Column("FIRST_NAME"));
Property(x => x.MiddleInitial, map => map.Column("MID_INITIAL"));
Property(x => x.LastName, map => map.Column("LAST_NAME"));
}
}
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
var json = config.Formatters.JsonFormatter;
json.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.Objects;
config.Formatters.Remove(config.Formatters.XmlFormatter);
config.Services.Replace(typeof(IHttpActionSelector), new HybridActionSelector());
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}/{action}/{actionid}/{subaction}/{subactionid}",
defaults: new { id = RouteParameter.Optional, action = RouteParameter.Optional,
actionid = RouteParameter.Optional, subaction = RouteParameter.Optional, subactionid = RouteParameter.Optional }
);
config.BindParameter( typeof( IPrincipal ), new ApiPrincipalModelBinder() );
// Uncomment the following line of code to enable query support for actions with an IQueryable or IQueryable<T> return type.
// To avoid processing unexpected or malicious queries, use the validation settings on QueryableAttribute to validate incoming queries.
// For more information, visit http://go.microsoft.com/fwlink/?LinkId=279712.
//config.EnableQuerySupport();
// To disable tracing in your application, please comment out or remove the following line of code
// For more information, refer to: http://www.asp.net/web-api
config.EnableSystemDiagnosticsTracing();
}
}
public class PersonsController : ApiController
{
private readonly ISessionFactory _sessionFactory;
public PersonsController (ISessionFactory sessionFactory)
{
_sessionFactory = sessionFactory;
}
// POST api/persons
[HttpPost]
public HttpResponseMessage Post(Person person)
{
var session = _sessionFactory.GetCurrentSession();
using (var tx = session.BeginTransaction())
{
try
{
if (!ModelState.IsValid)
{
return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState);
}
var result = session.Save(person);
var response = Request.CreateResponse<Person>(HttpStatusCode.Created, person);
string uriString = Url.Route("DefaultApi", new { id = person.Initials });
response.Headers.Location = new Uri(uriString);
tx.Commit();
return response;
}
catch (Exception)
{
tx.Rollback();
}
throw new HttpResponseException(HttpStatusCode.BadRequest);
}
}
}
提琴手信息: POST //localhost:60826/api/employees HTTP/1.1
请求标头: 用户代理:提琴手 内容类型:应用程序/json 主机:本地主机:xxxx 内容长度:71
请求正文:
{ "姓名首字母":"MMJ", "姓氏":"乔丹", “名字”:“迈克尔” }
此行永远不会将 uriString 设置为正确的值。 string uriString = Url.Route("DefaultApi", new { id = person.Initials }); 我也尝试过使用 Url.Link 而不是 Url.Route。我已经尝试在“新”块中添加控制器 =“Persons”,但这没有任何效果。为什么没有设置uriString?在这一点上,我会听取任何想法。
编辑 我试过了
string uriString = Url.Link("DefaultApi", new { controller = "Persons", id = person.Initials, action="", actionid="", subaction="", subactionid="" });
以及使用单独的路由配置
config.Routes.MapHttpRoute(
name: "PostApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional
} );
与
string uriString = Url.Link("PostApi", new { controller = "Persons", id = person.Initials});
没有运气。
解决方案
通过使用下面的代码行,我能够让这篇文章正常工作。我不完全确定这是否是正确的方法,所以如果有人知道不同,请分享。否则,我会很乐意使用这种方法。
response.Headers.Location = new Uri(this.Request.RequestUri.AbsoluteUri + "/" + person.Initials);
【问题讨论】:
标签: post asp.net-web-api asp.net-web-api-routing