ASP.NET Web API در سمت سرور، برای مدیریت ApiControllerها و در سمت کلاینتهای دات نتی آن، برای مدیریت HttpClient، به صورت پیش فرض از JSON.NET استفاده میکند. در ادامه نگاهی خواهیم داشت به تنظیمات JSON در سرور و کلاینتهای ASP.NET Web API.
آماده سازی یک مثال Self host
برای اینکه خروجیهای JSON را بهتر و بدون نیاز به ابزار خاصی مشاهده کنیم، میتوان یک پروژهی کنسول جدید را آغاز کرده و سپس آنرا تبدیل به Host مخصوص Web API کرد. برای اینکار تنها کافی است در کنسول پاور شل نیوگت دستور ذیل را صادر کنید:
سپس کنترلر Web API ما از کدهای ذیل تشکیل خواهد شد که در آن در متد Post، قصد داریم اصل محتوای دریافتی از کاربر را نمایش دهیم. توسط متد GetAll آن، خروجی نهایی JSON آن در سمت کاربر بررسی خواهد شد.
که در آن شیء کاربر چنین ساختاری را دارد:
برای اعمال تنظیمات self host ابتدا نیاز است یک کلاس Startup مخصوص Owin را تهیه کرد:
که سپس با فراخوانی چند سطر ذیل، سبب راه اندازی سرور Web API، بدون نیاز به IIS خواهد شد:
در ادامه اگر در سمت کلاینت، دستورات ذیل را برای دریافت لیست کاربران صادر کنیم:
به این خروجی خواهیم رسید:
همانطور که ملاحظه میکنید، مقدار Type مساوی صفر است. در اینجا چون Type را به صورت enum تعریف کردهایم، به صورت پیش فرض مقدار عددی عضو انتخابی در JSON نهایی درج میگردد.
تنظیمات JSON سمت سرور Web API
برای تغییر این خروجی، در سمت سرور تنها کافی است به کلاس Startup مراجعه و HttpConfiguration را به صورت ذیل تنظیم کنیم:
در اینجا با انتخاب StringEnumConverter، سبب خواهیم شد تا کلیه مقادیر enum، دقیقا مساوی همان مقدار اصلی رشتهای آنها در JSON نهایی درج شوند.
اینبار اگر برنامه را اجرا کنیم، چنین خروجی حاصل میگردد و در آن دیگر Type مساوی صفر نیست:
تنظیمات JSON سمت کلاینت Web API
اکنون در سمت کلاینت قصد داریم اطلاعات یک کاربر را با فرمت JSON به سمت سرور ارسال کنیم. روش متداول آن توسط کتابخانهی HttpClient، استفاده از متد PostAsJsonAsync است:
با این خروجی سمت سرور
در اینجا نیز Type به صورت عددی ارسال شدهاست. برای تغییر آن نیاز است به متدی با سطح پایینتر از PostAsJsonAsync مراجعه کنیم تا در آن بتوان JsonMediaTypeFormatter را مقدار دهی کرد:
خاصیت SerializerSettings کلاس JsonMediaTypeFormatter برای اعمال تنظیمات JSON.NET پیش بینی شدهاست.
اینبار مقدار دریافتی در سمت سرور به صورت ذیل است و در آن، Type دیگر عددی نیست:
مثال کامل این بحث را از اینجا میتوانید دریافت کنید:
UsersController.zip
آماده سازی یک مثال Self host
برای اینکه خروجیهای JSON را بهتر و بدون نیاز به ابزار خاصی مشاهده کنیم، میتوان یک پروژهی کنسول جدید را آغاز کرده و سپس آنرا تبدیل به Host مخصوص Web API کرد. برای اینکار تنها کافی است در کنسول پاور شل نیوگت دستور ذیل را صادر کنید:
PM> Install-Package Microsoft.AspNet.WebApi.OwinSelfHost
using System; using System.Collections.Generic; using System.Net; using System.Net.Http; using System.Threading.Tasks; using System.Web.Http; namespace WebApiSelfHostTests { public class UsersController : ApiController { public IEnumerable<User> GetAllUsers() { return new[] { new User{ Id = 1, Name = "User 1", Type = UserType.Admin }, new User{ Id = 2, Name = "User 2", Type = UserType.User } }; } public async Task<HttpResponseMessage> Post(HttpRequestMessage request) { var jsonContent = await request.Content.ReadAsStringAsync(); Console.WriteLine("JsonContent (Server Side): {0}", jsonContent); return new HttpResponseMessage(HttpStatusCode.Created); } } }
namespace WebApiSelfHostTests { public enum UserType { User, Admin, Writer } public class User { public int Id { set; get; } public string Name { set; get; } public UserType Type { set; get; } } }
using System.Web.Http; using Newtonsoft.Json; using Newtonsoft.Json.Converters; using Owin; namespace WebApiSelfHostTests { /// <summary> /// PM> Install-Package Microsoft.AspNet.WebApi.OwinSelfHost /// </summary> public class Startup { public void Configuration(IAppBuilder appBuilder) { var config = new HttpConfiguration(); config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{id}", defaults: new { id = RouteParameter.Optional } ); appBuilder.UseWebApi(config); } } }
var server = WebApp.Start<Startup>(url: BaseAddress); Console.WriteLine("Press Enter to quit."); Console.ReadLine(); server.Dispose();
using (var client = new HttpClient()) { var response = client.GetAsync(BaseAddress + "api/users").Result; Console.WriteLine("Response: {0}", response); Console.WriteLine("JsonContent (Client Side): {0}", response.Content.ReadAsStringAsync().Result); }
JsonContent (Client Side): [{"Id":1,"Name":"User 1","Type":1},{"Id":2,"Name":"User 2","Type":0}]
تنظیمات JSON سمت سرور Web API
برای تغییر این خروجی، در سمت سرور تنها کافی است به کلاس Startup مراجعه و HttpConfiguration را به صورت ذیل تنظیم کنیم:
public class Startup { public void Configuration(IAppBuilder appBuilder) { var config = new HttpConfiguration(); config.Formatters.JsonFormatter.SerializerSettings = new JsonSerializerSettings { Converters = { new StringEnumConverter() } };
اینبار اگر برنامه را اجرا کنیم، چنین خروجی حاصل میگردد و در آن دیگر Type مساوی صفر نیست:
JsonContent (Client Side): [{"Id":1,"Name":"User 1","Type":"Admin"},{"Id":2,"Name":"User 2","Type":"User"}]
تنظیمات JSON سمت کلاینت Web API
اکنون در سمت کلاینت قصد داریم اطلاعات یک کاربر را با فرمت JSON به سمت سرور ارسال کنیم. روش متداول آن توسط کتابخانهی HttpClient، استفاده از متد PostAsJsonAsync است:
var user = new User { Id = 1, Name = "User 1", Type = UserType.Writer }; var client = new HttpClient(); client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); var response = client.PostAsJsonAsync(BaseAddress + "api/users", user).Result; Console.WriteLine("Response: {0}", response);
JsonContent (Server Side): {"Id":1,"Name":"User 1","Type":2}
var jsonMediaTypeFormatter = new JsonMediaTypeFormatter { SerializerSettings = new JsonSerializerSettings { Converters = { new StringEnumConverter() } } }; var response = client.PostAsync(BaseAddress + "api/users", user, jsonMediaTypeFormatter).Result; Console.WriteLine("Response: {0}", response);
اینبار مقدار دریافتی در سمت سرور به صورت ذیل است و در آن، Type دیگر عددی نیست:
JsonContent (Server Side): {"Id":1,"Name":"User 1","Type":"Writer"}
مثال کامل این بحث را از اینجا میتوانید دریافت کنید:
UsersController.zip