私は数週間からASP.NET Coreに取り組んできました。私はこのブログに基づいて何かを達成しようとしていました: Microservices
私のproject.json
は次のとおりです。
{
"version": "1.0.0-*",
"compilationOptions": {
"emitEntryPoint": true
},
"dependencies": {
"Microsoft.AspNet.IISPlatformHandler": "1.0.0-rc1-final",
"Microsoft.AspNet.Server.Kestrel": "1.0.0-rc1-final",
"Microsoft.AspNet.Diagnostics": "1.0.0-rc1-*",
"Microsoft.AspNet.Mvc": "6.0.0-rc1-final",
"EntityFramework.Core": "7.0.0-rc1-final",
"EntityFramework.Commands": "7.0.0-rc1-final",
"EntityFramework.MicrosoftSqlServer": "7.0.0-rc1-final",
"EntityFramework.MicrosoftSqlServer.Design": "7.0.0-rc1-final",
"Microsoft.AspNet.Mvc.Formatters.Json": "6.0.0-rc1-final",
"Microsoft.AspNet.Mvc.Formatters.Xml": "6.0.0-rc1-final",
"System.Security.Cryptography.Algorithms": "4.0.0-beta-23516"
},
"commands": {
"web": "Microsoft.AspNet.Server.Kestrel",
"ef": "EntityFramework.Commands"
},
"frameworks": {
"dnxcore50": {
"dependencies": {
}
}
},
"exclude": [
"wwwroot",
"node_modules"
],
"publishExclude": [
"**.user",
"**.vspscc"
]
}
また、Startup.cs
のConfigureServices
メソッドは次のとおりです。
public void ConfigureServices(IServiceCollection services)
{
//Registering Authorization Database
AutorizationAccessRegisteration.RegisterComponents(services, Configuration);
services.AddMvcCore()
.AddJsonFormatters(a => a.ContractResolver = new CamelCasePropertyNamesContractResolver());
//Add cors built in support.
services.AddCors();
services.AddMvcCore().AddApiExplorer();
//Add MVC for supporting WebApi requests
#region MVC Add
services.AddMvc();
services.AddMvc().AddMvcOptions(options =>
{
options.RespectBrowserAcceptHeader = true;
// Input Formatters.
options.InputFormatters.Clear();
var jsonInputFormatter = new JsonInputFormatter()
{
SerializerSettings = new JsonSerializerSettings()
{
ContractResolver = new CamelCasePropertyNamesContractResolver()
,
DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate,
NullValueHandling = NullValueHandling.Ignore
}
};
options.InputFormatters.Add(jsonInputFormatter);
//Output formater
//as part of get/post request, set the header Accept = application/json or application/xml
var jsonOutputFormatter = new JsonOutputFormatter();
jsonOutputFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
jsonOutputFormatter.SerializerSettings.DefaultValueHandling = Newtonsoft.Json.DefaultValueHandling.Ignore;
options.OutputFormatters.Insert(0, jsonOutputFormatter);
options.OutputFormatters.Insert(1, new XmlDataContractSerializerOutputFormatter());
});
#endregion
}
そして、これがStartup.csのConfiure
メソッドです。
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
}
else if (env.IsStaging())
{
}
else if (env.IsProduction())
{
}
app.UseIISPlatformHandler();
app.UseCors(builder =>
builder.WithOrigins("*").AllowAnyHeader().AllowAnyMethod());
//Middlewares addition to the pipelines:
/// We add the middlewares in the following fashion:
/// - Exception Handler
/// - Logger
/// - Authorization Handler
/// There is a big reason of doing that.
///
app.UseExceptionHandler();
app.UseLoggerHandler();
app.UseAuthorizationHandler();
app.UseMvc();
}
AuthorizationControllerは次のとおりです。
[Route("api/Authorization")]
public class AuthorizationController : Controller
{
.
[HttpPost]
public void Post([FromBody]string value)
{
}
.
}
Post
メソッドには、元々[FromBody]string[] value
がありました。単純なstring
タイプにすることで、さらに単純化しました。 ChromeでHTTP request
を送信するためにAdvance Rest Clientを使用しています。string[]
がタイプである場合、私は本文で次の値を使用していました:
{
["value","sdjklgsdjlg"]
}
パラメータを簡略化した後、次のボディでリクエストを送信してみました:
{"sdjklgsdjlg"}
これも試しました:
{"value":"sdjklgsdjlg"}
何か不足していますか?以前読んだ、古いWebApiがJSONの複雑なオブジェクトと通常のパラメーターへのマッピングに関連して機能していた方法は、.NET Coreでも同様に機能します。
また、breakpointがすべてのミドルウェアとコントローラーで正常にヒットすることを詳しく説明します。しかし、ミドルウェアのいずれも、リクエストのストリーム関連のものを読み取ることができないようです:
問題が発生している場所を教えてください。どうもありがとう!
[FromBody]
は、登録されたフォーマッターを使用して、送信されたデータの本文全体を、それが適用される単一のパラメーターにデコードします。デフォルトでは、登録された唯一のフォーマッターがJSONを受け入れます。
JSONでは、文字列を直接表す有効な方法はありません。{"sdjklgsdjlg"}
は有効なJSONではありませんが、{"value":"sdjklgsdjlg"}
は有効ですが、単純な文字列パラメータにデシリアライズされません。 編集: @tmgによる回答を参照してください。これは、構文{ "": "sdjklgsdjlg" }
を使用して行うことができます
したがって、本文から取得しようとしている入力を表すために、ある種の特定のモデルクラスが必要になります。たとえば、次のようになります。
public class AuthRequest {
public string Value { get; set; }
}
次に、正常に実行できるはずです。
[Route("api/Authorization")]
public class AuthorizationController : Controller
{
[HttpPost]
public void Post([FromBody]AuthRequest authReq)
{
// authReq.Value should have your value in
}
}
これに{ "Value": "some value" }
を投稿すると、期待どおりに動作するはずです。
これは私にとってはうまくいきます:
[HttpPost]
public async Task<IActionResult> CreateApp([FromQuery]string userId)
{
string appDefinition = await new StreamReader(Request.Body).ReadToEndAsync();
var newAppJson = JObject.Parse(appDefinition);
...
マーク・ヒューズの答えは、ある時点まで正解です。この形式のjsonを投稿した場合、{ "": "sdjklgsdjlg" }
モデルバインダーは、ラッパーモデルを必要とせずに、それを単純な文字列モデルにバインドできるはずです。
次のようなこともできます:
[HttpPost]
public System.Net.Http.HttpResponseMessage Post([FromBody]dynamic value)
{
//...
}
またはユーザー[FromQuery]
と直接クエリ文字列値を渡します。
私はここで遅れていますが、正確な理由を共有して、他のユーザーが正確な情報を入手できるようにしたいと考えています。
データをJSONオブジェクトとして投稿しているため、コントローラーで値を取得できません。
{"value":"sdjklgsdjlg"} //See the curly braces represent an object.
これを解決するには、このデータをバインドする別のオブジェクトが必要です。コントローラのアクションでこのようなもの:
[HttpPost]
public void Post([FromBody]CustomViewModel data)
{
...
//here you can get value as: data.Value
}
ここで、CustomViewModelはクラスです。
public CustomViewModel
{
public string Value { get; set; }
}
現在のアクションシグネチャに従ってデータを取得する場合:
[HttpPost]
public void Post([FromBody]string value)
{
...
}
次に、データをリクエスト本文でJSON文字列として渡す必要があります。
"sdjklgsdjlg" //notice without any curly braces and property name
同様に文字列配列アクションの場合:
[HttpPost]
public void Post([FromBody]IEnumerable<string> values)
{
...
}
リクエスト本文に文字列のJSON配列を渡します。
["item1", "item2"]
すべての依存関係のRC2バージョンを使用する必要があります。
https://github.com/aspnet/KestrelHttpServer/issues/915 があります。System.Threading.Tasks.Extensionsのバージョンはデフォルトで4.0.0です。したがって、project.jsonファイルでこのパッケージのバージョンを明示的に指定する必要があります。
"System.Threading.Tasks.Extensions": "4.0.0-rc2-24027"