解決しました!解決策については、投稿の下部を確認してください。
だから私は取り組んでいるWeb APIを持っていて、getsはうまく機能し、基本的な型だけで構成される単純な型ではpostがうまく機能します。動作するものの例:
public class Investigator
{
public int InvestigatorId { get; set; }
public string Name { get; set; }
}
ただし、ネストされた型では、ネストされたオブジェクトはデフォルトの表現 (型に応じて 0 と null) として返されます。機能していない例を次に示します。
public class Project
{
public int ProjectId { get; set; }
public string ProjectName { get; set; }
public virtual State State { get; set; }
public string City { get; set; }
public virtual Investigator ProjectInvestigator { get; set; }
}
プロジェクトを投稿するために uri を呼び出すと、ネストされた型を除いてすべてのフィールドが正常に処理されます。ただし、ネストされた型はデフォルトの表現に戻ります (調査者は ID に 0、名前に null を返します)。投稿リクエストに調査者を含めないと、調査者オブジェクト自体がデフォルト オブジェクトではなく null として送信されます。したがって、少なくともコードで見られることはわかっていますが、正しく逆シリアル化されていません。これは何が原因で、逆シリアル化される前に入ってくるデータをどこで確認できますか?
関連する可能性のある他のコード セクションは、コントローラーです。
public class ProjectsController : ApiController
{
private NovascotiaContext db = new NovascotiaContext();
protected override void Initialize(System.Web.Http.Controllers.HttpControllerContext controllerContext)
{
base.Initialize(controllerContext);
db.Configuration.ProxyCreationEnabled = false;
}
// GET api/Projects
public IEnumerable<Project> GetProjects()
{
return db.Projects.AsEnumerable();
}
// GET api/Projects/5
public Project GetProject(int id)
{
Project project = db.Projects.Find(id);
if (project == null)
{
throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotFound));
}
return project;
}
// PUT api/Projects/5
public HttpResponseMessage PutProject(int id, Project project)
{
if (!ModelState.IsValid)
{
return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState);
}
if (id != project.ProjectId)
{
return Request.CreateResponse(HttpStatusCode.BadRequest);
}
db.Entry(project).State = EntityState.Modified;
try
{
db.SaveChanges();
}
catch (DbUpdateConcurrencyException ex)
{
return Request.CreateErrorResponse(HttpStatusCode.NotFound, ex);
}
return Request.CreateResponse(HttpStatusCode.OK);
}
// POST api/Projects
public HttpResponseMessage PostProject([FromBody]Project project)
{
if (ModelState.IsValid)
{
db.Projects.Add(project);
db.SaveChanges();
HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.Created, project);
response.Headers.Location = new Uri(Url.Link("DefaultApi", new { id = project.ProjectId }));
return response;
}
else
{
return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState);
}
}
// DELETE api/Projects/5
public HttpResponseMessage DeleteProject(int id)
{
Project project = db.Projects.Find(id);
if (project == null)
{
return Request.CreateResponse(HttpStatusCode.NotFound);
}
db.Projects.Remove(project);
try
{
db.SaveChanges();
}
catch (DbUpdateConcurrencyException ex)
{
return Request.CreateErrorResponse(HttpStatusCode.NotFound, ex);
}
return Request.CreateResponse(HttpStatusCode.OK, project);
}
protected override void Dispose(bool disposing)
{
db.Dispose();
base.Dispose(disposing);
}
}
そして、Web API 構成:
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
var appXmlType = config.Formatters.XmlFormatter.SupportedMediaTypes.FirstOrDefault(t => t.MediaType == "application/xml");
config.Formatters.XmlFormatter.SupportedMediaTypes.Remove(appXmlType);
// 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();
}
}
編集:投稿リクエストは、HTTPService クラスを介して as3/flex で完了しています:
var p:Project = new Project();
p.City = "ACity";
p.ProjectName = "AProjectName";
var state:data.State = new data.State();
state.StateId = 98;
state.StateName = "Tennessee";
p.State = state;
var investigator:Investigator = new Investigator();
investigator.InvestigatorId = 1;
investigator.Name = "John Doe";
p.ProjectInvestigator = investigator;
projectPostService.send(p);
projectPostService は、method="POST" の HTTPService オブジェクトです。奇妙なことは、これを書いているときに、サービスにアクセスするための簡単なページを作成したことです。これは明らかに as3/flex と Web API 間の通信に関するものです。動作するページは次のとおりです。
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
<title></title>
<script src="Scripts/jquery-1.8.2.js"></script>
<script type="text/javascript">
$(document).ready(function () {
alert("ready");
var project = {
"ProjectId": 2,
"ProjectName": "Aprojectname",
"State": { "StateId": 98, "StateName": "Tennessee" },
"ProjectInvestigator": { "InvestigatorId": 1, "Name": "John Doe" }
};
$.ajax({
url: "http://localhost/api/Projects",
type: 'POST',
dataType: 'json',
data: project,
success: function (data) {
alert(JSON.stringify(data));
},
failure: function (data) {
alert('fail');
}
});
});
</script>
</head>
<body>
<form id="form1" runat="server">
<div>
</div>
</form>
</body>
</html>
より具体的な問題に合わせてタイトルを編集しました。as3/flex と Web API プロジェクトの間でこれを機能させる経験があれば、助けていただければ幸いです。
さらに別の編集: HTTPService クラスは、送信されるオブジェクトの各プロパティを通過し、それを名前と値のペアに変換するようです。これは「深さ 0」のフィールドでは問題なく機能しますが、ネストされたオブジェクトの場合、フィールドは "field" : "[Object object]" のようなものになります。
解決策: サービス URL をヒットするために as3 で URLLoader を使用することになりました。ネストされた型が空になり続けたため、しばらくの間、ネストされたオブジェクトの投稿に失敗しました。私にとっての解決策は、以前に見落としていたコンテンツ タイプをテキストに設定することでした。この問題に遭遇した他の人が上記のようなサービスにアクセスするには、次の例があります。
var p:Project = new Project();
p.City = "ACity";
p.ProjectName = "AProjectName";
var state:data.State = new data.State();
state.StateId = 98;
state.StateName = "Tennessee";
p.State = state;
var investigator:Investigator = new Investigator();
investigator.InvestigatorId = 1;
investigator.Name = "John Doe";
p.ProjectInvestigator = investigator;
var loader:URLLoader = new URLLoader();
var hdr:URLRequestHeader = new URLRequestHeader("Content-Type", "application/json");
var request:URLRequest = new URLRequest("http://localhost/api/Projects");
request.requestHeaders.push(hdr);
request.data = com.adobe.serialization.json.JSON.encode(p);
request.contentType = "TEXT";
request.method = "POST";
loader.addEventListener(Event.COMPLETE, function(e:Event):void{
trace(loader.data); //return
});
loader.load(request);