Vaziyat kodi bilan ASP.NET Core return JSON

JSON-ni HTTP vaziyat kodi bilan qaytarishning to'g'ri usulini izlayapman. NET Core Web API controller. Men buni quyidagi tarzda ishlatish uchun foydalanaman:

public IHttpActionResult GetResourceData()
{
    return this.Content(HttpStatusCode.OK, new { response = "Hello"});
}

Bu 4,6 MVC dasturda edi, lekin endi. NET Core bilan ushbu IHttpActionResult kodi ActionResult va shunga o'xshash tarzda foydalanishga o'xshamaydi:

public ActionResult IsAuthenticated()
{
    return Ok(Json("123"));
}

Biroq, serverdagi javob quyidagi rasmdagi kabi g'alati:

enter image description here

Men faqat Web API tekshirgichni JSONni Web API 2 da qilgan kabi HTTP holat kodi bilan qaytarishini xohlayman.

66
"OK" usullari 200 holat kodi sifatida qaytariladi. Oldindan belgilangan usullar barcha umumiy hollarni qamrab oladi. 201-raqamni qaytarish (yangi manba joylashuvi bilan bosh sarlavhasi) uchun CreatedAtRoute va boshqalar.
qo'shib qo'ydi muallif Tseng, manba

6 javoblar

JsonResult bilan javob beradigan eng asosiy versiya:

// GET: api/authors
[HttpGet]
public JsonResult Get()
{
    return Json(_authorRepository.List());
}

Biroq, bu sizning masala bo'yicha yordam bermaydi, chunki siz o'z javob kodingiz bilan aniq ishlamaysiz.

Status natijalarini nazorat qilish uchun ActionResult kodini qaytarishingiz kerak. Bu StatusCodeResult turidan foydalanishingiz mumkin.

misol uchun:

// GET: api/authors/search?namelike=foo
[HttpGet("Search")]
public IActionResult Search(string namelike)
{
    var result = _authorRepository.GetByNameSubstring(namelike);
    if (!result.Any())
    {
        return NotFound(namelike);
    }
    return Ok(result);
}

Note both of these above examples came from a great guide available from Microsoft Documentation: Formatting Response Data


Qo'shimcha narsalar

Juda tez-tez uchratadigan masala shundaki, WebAPI haqida batafsilroq tekshirishni xohlardim, faqat VS.da "Yangi loyiha" shablonidan oldindan tuzilgan sozlamalar bilan borishdan ko'ra ko'proq narsani istardim.

Keling, sizda ba'zi asoslar borligiga ishonch hosil qilamiz ...

1-qadam: Xizmatingizni sozlang

ASP.NET Core WebAPI-ni JSON Serialized Object bilan vaziyat kodini to'liq boshqarish bilan javob berishga erishish uchun, sizning kodingizda AddMvc() xizmatini qo'shganingizga ishonch hosil qilib, siz boshlashingiz kerak. Odatda Startup.cs da joylashgan ConfigureServices usuli.

AddMvc() , boshqa spam-tiplarga javob berish bilan birga JSON uchun Input/Output Formatterni avtomatik tarzda kiritishi kerakligini ta'kidlash muhim.

Agar loyihangiz to'liq boshqarish va to'liq talab qilsa va WebAPI'nizin turli xil spam-turlari, jumladan, application/json turlari (masalan, standart brauzer so'rovi) siz uni quyidagi kod bilan qo'lda belgilashingiz mumkin:

public void ConfigureServices(IServiceCollection services)
{
   //Build a customized MVC implementation, without using the default AddMvc(), instead use AddMvcCore().
   //https://github.com/aspnet/Mvc/blob/dev/src/Microsoft.AspNetCore.Mvc/MvcServiceCollectionExtensions.cs

    services
        .AddMvcCore(options =>
        {
            options.RequireHttpsPermanent = true;//does not affect api requests
            options.RespectBrowserAcceptHeader = true;//false by default
            //options.OutputFormatters.RemoveType();

            //remove these two below, but added so you know where to place them...
            options.OutputFormatters.Add(new YourCustomOutputFormatter()); 
            options.InputFormatters.Add(new YourCustomInputFormatter());
        })
        //.AddApiExplorer()
        //.AddAuthorization()
        .AddFormatterMappings()
        //.AddCacheTagHelper()
        //.AddDataAnnotations()
        //.AddCors()
        .AddJsonFormatters();//JSON, or you can build your own custom one (above)
}

Boshqa serializatsiya formatiga (protobuf, tejamkorlik, va hokazo) javob berishni xohlashingiz mumkin bo'lgan holatlarda siz o'zingizning maxsus Kirish/Chiqarish formatterlarini qo'shish uchun sizda usul ham mavjudligini ko'rasiz.

Yuqoridagi kodning ko'pligi asosan AddMvc() usulining ikki nusxasi. Shu bilan birga, biz har bir "default" xizmatini shablon bilan oldindan jo'natilgan joyga borish o'rniga har bir xizmatni belgilab, o'zimiz amalga oshiryapmiz. Kod bloklaridagi havzani havolani qo'shib qo'yganman yoki AddMvc() GitHub omboridan .

Esda tutingki, uni dastlab amalga oshirishni emas, balki "asl holatini bekor qilish" yo'li bilan hal qilishga harakat qiladigan ba'zi qo'llanmalar mavjud ... Agar siz hozir ommaviy dastur bilan ishlayotgan bo'lsak, keraksiz ish, yomon kod va shubhasiz, tez orada yo'q bo'lib ketadigan eski odat.


2-qadam: Bir tekshirgich yarating

Men sizning savolingizni tartiblangan holda olish uchun sizni to'g'ridan-to'g'ri oldinga ko'rsataman.

public class FooController
{
    [HttpPost]
    public async Task Create([FromBody] Object item)
    {
        if (item == null) return BadRequest();

        var newItem = new Object();//create the object to return
        if (newItem != null) return Ok(newItem);

        else return NotFound();
    }
}

Step 3: Check your Content-Type and Accept

Siz so'rovingiz dagi Tarkibiy-toifa va qabul qilish sarlavhalarining to'g'ri o'rnatilganligiga ishonch hosil qiling. Sizning holatda (JSON) siz uni application/json sifatida o'rnatishingizni xohlaysiz.

Agar siz WebAPI-nizni JSON deb javob berishni xohlasangiz, so'rov sarlavhasi nimadan iboratligini bilmasangiz, buni juftlikdan shaklida qilishingiz mumkin.

Way 1 As shown in the article I recommended earlier (Formatting Response Data) you could force a particular format at the Controller/Action level. I personally don't like this approach... but here it is for completeness:

Maxsus formatga majbur qilish Agar ma'lum bir harakat uchun javob formatlarini cheklashni xohlasangiz,   Filtrni ishlab chiqaradi. [Ishlab chiqaradigan] filtr javobni belgilaydi   ma'lum bir harakat (yoki tekshiruvchi) uchun formatlar. Eng Filtrlar kabi, bu   amalda, nazoratchi yoki global miqyosda qo'llanilishi mumkin.

  [ishlab chiqaradi ("application/json")]
public class AuthorsController
 
-ni tanlang      

[ishlab chiqaradi]] filtri ichidagi barcha harakatlarga majbur qiladi    AuthorsController , boshqa bo'lsa ham JSON formatidagi javoblarni qaytaradi   formatterlar dastur uchun tuzilgan va mijoz taqdim etgan   Boshqa

Way 2 My preferred method is for the WebAPI to respond to all requests with the format requested. However, in the event that it doesn't accept the requested format, then fall-back to a default (ie. JSON)

Birinchidan, bu sizning tanlovingizda qayd etishingiz kerak (biz yuqorida aytib o'tilganidek, xatolikni qayta ishlashimiz kerak)

options.RespectBrowserAcceptHeader = true;//false by default

Nihoyat, xizmatlarni ishlab chiqaruvchilarda aniqlangan formatlashtiruvchilar ro'yxatini qayta tartibga solish orqali, veb-xosting siz ro'yxatning yuqori qismida joylashadigan formatterga (masalan, 0-pozitsiyasiga) sukut qiladi.

More information can be found in this .NET Web Development and Tools Blog entry

96
qo'shib qo'ydi
O'rnatilganida: RespectBrowserAcceptHeader = true; Siz buni nima uchun qilayotganingizni tushuntirmaysiz va odatda keraksiz va buning uchun noto'g'ri bo'ladi. Brauzerlar html so'raydilar va shuning uchun ular formatter tanlashga ta'sir qilmasligi kerak (bu xrom afsuski, xml so'ramoqda). Qisqasi, men sizni ushlab turishim kerak bo'lgan narsadir, va siz o'zingiz belgilagan dastlabki holat allaqachon odatiy xatti-harakatlar
qo'shib qo'ydi muallif Yishai Galatzer, manba
Siz kiritgan sa'y-harakatlaringiz uchun juda ko'p narsa. Javobingiz IActionResult ni amalga oshirish uchun menga ilhom berdi Return Ok (new {response = "123"});
qo'shib qo'ydi muallif Rossco, manba
@Rossco Muammo yo'q. Umid qilamanki kodning qolgan qismi sizni loyihangiz rivojlanishiga yordam beradi.
qo'shib qo'ydi muallif Svek, manba
Ushbu mavzuni kengaytirish uchun men bu erda WebAPI dasturini amalga oshirish uchun qo'shimcha va to'liqroq qo'llanma yaratdim: stackoverflow.com/q/42365275/3645638
qo'shib qo'ydi muallif Svek, manba
@YishaiGalatzer Mening javobimning asosiy qismi mijoz va API mantig'i o'rtasida standart qidiruv dasturni qanday ochish kerakligini ta'kidlash edi. Menimcha, RespectBrowserAcceptHeader sizning mijozlaringiz noto'g'ri so'rovlarni yubormaganligidan amin bo'lishni istasangiz, muqobil ketma-ket yoki undan foydalanishni qo'llashda juda muhimdir. Shuning uchun, "Loyihangizga to'liq boshqarish kerak bo'lsa va siz" xizmatni aniq belgilashni istasangiz " ni ta'kidlab, yuqoridagi bloklangan taklifni ushbu bayonotning yuqorisiga e'tibor bering.
qo'shib qo'ydi muallif Svek, manba

Ko'pgina keng tarqalgan vaziyat kodlari uchun oldindan belgilangan usullar mavjud.

  • Ok(result) returns 200 with response
  • CreatedAtRoute returns 201 + new resource URL
  • NotFound returns 404
  • BadRequest returns 400 etc.

BaseController-ga qarang. .cs va Controller.cs .

Lekin, agar siz haqiqatdan ham maxsus kodni o'rnatish uchun StatusCode dan foydalanishingiz mumkin bo'lsa, lekin siz kodni kam o'qilishi mumkinligi va siz kodni takrorlashingiz kerak (masalan, YaratilganAtRoute ).

public ActionResult IsAuthenticated()
{
    return StatusCode(200, Json("123"));
}
29
qo'shib qo'ydi

ASP.NET Core 2.0 bilan ob'ektni Veb API dan (MVC bilan birlashtirilgan va bir xil asosiy sinf Controller dan foydalanadigan) mavjud

public IActionResult Get()
{
    return new OkObjectResult(new Item { Id = 123, Name = "Hero" });
}

Shuni e'tibor bering

  1. 200 OK holati kodi bilan qaytariladi ( Object Object Ok )
  2. Kontentni muhokama qilish, ya'ni so'rovda Accept header-ga asoslanadi. Agar so'rovda Accept: application/xml yuborilsa, u xml sifatida qaytadi. Hech narsa yuborilmasa, JSON sukut.

Agar maxsus vaziyat kodi bilan yuborish kerak bo'lsa, uning o'rniga ObjectResult yoki StatusCode dan foydalaning. Ikkalasi ham xuddi shunday narsani qilmoqda va tarkibni muhokama qilishni qo'llab-quvvatlaydi.

return new ObjectResult(new Item { Id = 123, Name = "Hero" }) { StatusCode = 200 };
return StatusCode( 200, new Item { Id = 123, Name = "Hero" });

Agar siz ayniqsa JSON sifatida qaytish ni xohlasangiz, ikkita yo'l bor

//GET http://example.com/api/test/asjson
[HttpGet("AsJson")]
public JsonResult GetAsJson()
{
    return Json(new Item { Id = 123, Name = "Hero" });
}

//GET http://example.com/api/test/withproduces
[HttpGet("WithProduces")]
[Produces("application/json")]
public Item GetWithProduces()
{
    return new Item { Id = 123, Name = "Hero" };
}

Shuni e'tibor bering

  1. Both enforces JSON in two different ways.
  2. Both ignores content negotiation.
  3. First method enforces JSON with specific serializer Json(object).
  4. Second method does the same by using Produces() attribute (which is a ResultFilter) with contentType = application/json

Ularni rasmiy hujjatlar orqali o'qishingiz mumkin. Bu yerda filtrlar haqida ma'lumot oling.

Namunalarda ishlatiladigan oddiy model sinf

public class Item
{
    public int Id { get; set; }
    public string Name { get; set; }
}

15
qo'shib qo'ydi
Bu yaxshi javob, chunki u savolga diqqatni qaratadi va qisqacha ba'zi amaliyotlarni tushuntiradi.
qo'shib qo'ydi muallif netfed, manba

Men bilan eng oson yo'li:

return new JsonResult(result)
{
    StatusCode = 201//Status code here 
};
9
qo'shib qo'ydi
Bu @tseng javobidan yaxshiroq deb o'ylayman, chunki uning echimi Status kodlari va boshqalar uchun takrorlangan maydonlarni o'z ichiga oladi.
qo'shib qo'ydi muallif Christian Sauer, manba
Sizning yaxshilanishingiz Microsoft.AspNetCore.Http-da belgilangan StatusCode-dan foydalanishdir. Quyidagi kabi: yangi JsonResult (new {}) ni qaytaring (statusCode = StatusCodes.Status404NotFound);
qo'shib qo'ydi muallif Bryan Bedard, manba

Bu mening eng oson echim:

public IActionResult InfoTag()
{
    return Ok(new {name = "Fabio", age = 42, gender = "M"});
}

yoki

public IActionResult InfoTag()
{
    return Json(new {name = "Fabio", age = 42, gender = "M"});
}
2
qo'shib qo'ydi

Iltimos, quyidagi kodni ko'rib chiqing, turli xil JSON kodlari bilan bir nechta vaziyat kodini boshqarishingiz mumkin

public async Task GetAsync()
{
    try
    {
        using (var entities = new DbEntities())
        {
            var resourceModelList = entities.Resources.Select(r=> new ResourceModel{Build Your Resource Model}).ToList();

            if (resourceModelList.Count == 0)
            {
                return this.Request.CreateResponse(HttpStatusCode.NotFound, "No resources found.");
            }

            return this.Request.CreateResponse>(HttpStatusCode.OK, resourceModelList, "application/json");
        }
    }
    catch (Exception ex)
    {
        return this.Request.CreateResponse(HttpStatusCode.InternalServerError, "Something went wrong.");
    }
}
1
qo'shib qo'ydi
Yo'q. Bu yomon.
qo'shib qo'ydi muallif Phillip Copley, manba
Javascript UZB
Javascript UZB
99 ishtirokchilar

@js_uzb @vuejs_uz @react_uz @nodejs_uz @angular_uz @ngTashkent @yiiframework_uz @laravel_uz @linux_uzbek @python_uz @swift_uzb —————— @uzdevgroup @UzGeeksGroup ——— @UzDev_Jobs @jobs_uzb