Perutean atribut untuk dua tindakan mengarah ke templat jalur OData yang tidak valid

Jadi saya memiliki dua fungsi yang mengembalikan pelanggan, yang diberi makan oleh dua parameter berbeda. Yang satu adalah ID pelanggan dan yang lainnya adalah nomor pelanggannya.

Pengontrol saya:

using System.Linq;
using System.Net;
using System.Web.Http;
using System.Web.OData;
using System.Web.OData.Routing;
using Models;
using AutoMapper;
using AutoMapper.QueryableExtensions;
using System.Web.OData.Extensions;
using Importing;
using Objects;
using Microsoft.OData;

namespace Controllers
{
    public class CustomersController : ODataController
    {
        // GET: CustomerByCNO(5)
        [HttpGet]
        [ODataRoute("CustomerByCNO({key})")]
        [EnableQuery]
        public SingleResult<CustomerDTO> GetCustomerByCNO([FromODataUri]string key)
        {
            Import i = new Import();

            var customer = i.GetCustomer(key).ProjectTo<CustomerDTO>().AsQueryable();

            return SingleResult.Create(customer);
        }

        // GET: Customer(5)
        [HttpGet]
        [ODataRoute("Customer({id})")]
        [EnableQuery]
        public SingleResult<CustomerDTO> Get([FromODataUri]int id)
        {
            Import i = new Import();

            var customer = i.GetCustomer(id).ProjectTo<CustomerDTO>().AsQueryable();

            return SingleResult.Create(customer);
        }
    }
}

Inisialisasi:

using AutoMapper;
using Models;
using Objects;
using System.Web.Http;
using System.Web.OData.Builder;
using System.Web.OData.Extensions;
using Microsoft.OData.Edm;

namespace API
{
    public static class WebApiConfig
    {
        public static void ConfigureAPI(HttpConfiguration config)
        {
            config.MapODataServiceRoute(
                routeName: "odata",
                routePrefix: "",
                model: GetEdmModel()
            );

            config.EnsureInitialized();
        }

        private static IEdmModel GetEdmModel()
        {
            ODataConventionModelBuilder builder = new ODataConventionModelBuilder
            {
                Namespace = "Controllers",
                ContainerName = "DefaultContainer"
            };
            builder.EntitySet<CustomerDTO>("Customer")
                .EntityType.HasKey(c => c.Id)
                .CollectionProperty(c => c.CustomFields);

            var edmModel = builder.GetEdmModel();
            return edmModel;
        }
    }
}

Meskipun fungsi kedua berfungsi sebagaimana mestinya, fungsi pertama tidak dan fungsi PastikanInitialized() memunculkan pernyataan InvalidOperationException, bahwa ini bukan templat jalur OData yang valid dan tidak ada sumber daya yang ditemukan. Bagaimana saya bisa membuat ini berfungsi? Tidak begitu yakin apa yang saya lewatkan di sini.

PEMBARUAN 1:

Mengubah metode Pengontrol menjadi ini:

        [HttpGet]
        [ODataRoute("CustomerByNo(No={no})")]
        public SingleResult<CustomerDTO> CustomerByNo([FromODataUri] int no)
        {
            Import i = new Import();

            var customer = i.GetCustomer(no.ToString()).ProjectTo<CustomerDTO>().AsQueryable();

            return SingleResult.Create(customer);
        }

dengan baris tambahan ini di konfigurasi:

        builder.Function("CustomerByNo").Returns<SingleResult<CustomerDTO>>().Parameter<int>("No");

Dibuat agar saya dapat mengakses fungsinya setidaknya. Saya juga harus mengubah parameter menjadi int, sepertinya tidak menyukai string? Namun nilai yang dikembalikan tidak dideserialisasi dan ditampilkan seperti biasa. Juga jika saya meninggalkan baris [EnableQuery] dalam deklarasi metode, panggilan akan macet dan mengatakan bahwa ia tidak tahu cara melakukan deserialisasi karena saya kira tidak terikat pada kumpulan entitas Pelanggan.

Namun mencobanya dengan cara ini, mengarah ke pesan kesalahan asli, bahwa sumber daya tidak dapat ditemukan:

        builder.EntityType<CustomerDTO>().Collection.Function("CustomerByNo").Returns<SingleResult<CustomerDTO>>().Parameter<int>("No");

person Peter    schedule 15.05.2018    source sumber


Jawaban (1)


Anda harus mendeklarasikan fungsi odata khusus Anda dalam model konvensi:

FunctionConfiguration customerByCNOFunction = builder.Function("CustomerByCNO");
customerByCNOFunction.Returns<CustomerDTO>();
customerByCNOFunction.Parameter<string>("key");

Memperbarui :

Jawaban pertama saya adalah mendeklarasikan fungsi yang mengembalikan tipe yang tidak dapat dikueri di odata. Untuk mengaktifkan kueri, fungsi tersebut perlu mengembalikan entitas odata dari kumpulan entitas :

builder.Function("CustomerByNo").ReturnsFromEntitySet<CustomerDTO>("Customer").Parameter<int>("No")
person J.Loscos    schedule 15.05.2018
comment
Terima kasih! Tapi ini tidak berhasil. Menambahkan SingleResult dari CustomerDTO sebagai imbalannya, tapi itu tidak masalah. Itu hanya memberi saya 404. - person Peter; 16.05.2018
comment
Untuk memastikan Anda menggunakan url yang benar, url fungsi odata khusus adalah yourhost/CustomerByCNO(key) Nama pengontrol tidak ada di url - person J.Loscos; 16.05.2018
comment
Ya :) Periksa hasil edit saya, mungkin itu akan memberi Anda lebih banyak info orang dalam - person Peter; 16.05.2018
comment
Coba dengan builder.Function(CustomerByCNO).ReturnsCollectionFromEntitySet‹CustomerDTO›(Customer).Parameter‹int›(No) Dengan begitu ia akan mengetahui bahwa tipe hasil berasal dari entitasSet pelanggan - person J.Loscos; 16.05.2018
comment
builder.Function(CustomerByNo).ReturnsFromEntitySet‹CustomerDTO›(Customer).Parameter‹int›(Tidak); Bekerja seperti pesona. Terima kasih! :D - person Peter; 16.05.2018
comment
bagus :) Saya memperbarui jawaban saya untuk memasukkan solusi yang tepat - person J.Loscos; 16.05.2018