ตัวควบคุมเดียวที่มีวิธีการหลาย GET ใน ASP.NET Web API


167

ใน Web API ฉันมีคลาสของโครงสร้างที่คล้ายกัน:

public class SomeController : ApiController
{
    [WebGet(UriTemplate = "{itemSource}/Items")]
    public SomeValue GetItems(CustomParam parameter) { ... }

    [WebGet(UriTemplate = "{itemSource}/Items/{parent}")]
    public SomeValue GetChildItems(CustomParam parameter, SomeObject parent) { ... }
}

เนื่องจากเราสามารถทำแผนที่วิธีการแต่ละอย่างมันง่ายมากที่จะได้รับการร้องขอที่ถูกต้องในสถานที่ที่เหมาะสม สำหรับการเรียนที่คล้ายกันซึ่งมีเพียงคนเดียวGETวิธี แต่ยังมีพารามิเตอร์ที่ผมใช้ประสบความสำเร็จObject IActionValueBinderอย่างไรก็ตามในกรณีที่อธิบายไว้ข้างต้นฉันได้รับข้อผิดพลาดต่อไปนี้:

Multiple actions were found that match the request: 

SomeValue GetItems(CustomParam parameter) on type SomeType

SomeValue GetChildItems(CustomParam parameter, SomeObject parent) on type SomeType

ฉันกำลังพยายามที่จะแก้ไขปัญหานี้โดยเอาชนะExecuteAsyncวิธีการApiControllerแต่ไม่มีโชคมาก่อน มีคำแนะนำในเรื่องนี้ไหม?

แก้ไข: ฉันลืมที่จะพูดถึงว่าตอนนี้ฉันกำลังพยายามย้ายรหัสนี้บน ASP.NET Web API ซึ่งมีวิธีการกำหนดเส้นทางที่แตกต่างกัน คำถามคือฉันจะทำให้โค้ดทำงานบน ASP.NET Web API ได้อย่างไร


1
คุณยังได้ {parent} เป็น RouteParameter.Optional หรือไม่
Antony Scott

ใช่ฉันทำ. บางทีฉันใช้ IActionValueBinder ในทางที่ผิดเพราะสำหรับประเภทเช่น int id (เหมือนในตัวอย่าง) มันใช้งานได้ดี
paulius_l

ขออภัยฉันควรชัดเจนขึ้น ฉันคิดว่าการมีเป็นตัวเลือกจะหมายความว่าตรงกับเส้นทางของรายการรวมถึงเส้นทางของรายการย่อยซึ่งจะอธิบายข้อความแสดงข้อผิดพลาดที่คุณเห็น
Antony Scott

ขณะนี้เรากำลังมีความสับสนถ้าแนวทางด้านล่าง (มีหลายเส้นทาง) ขัดต่อกฎ REST ที่เหมาะสมหรือไม่ ในความคิดของฉันมันดี เพื่อนร่วมงานของฉันคิดว่ามันไม่ดี ความคิดเห็นใด ๆ เกี่ยวกับเรื่องนี้?
Remy

โดยทั่วไปแล้วฉันต่อต้านมันเมื่อเริ่มอ่าน REST ฉันยังไม่แน่ใจว่านี่เป็นวิธีการที่เหมาะสมหรือไม่ แต่บางครั้งก็สะดวกกว่าหรือเป็นมิตรกับผู้ใช้ดังนั้นการดัดกฏเล็กน้อยอาจไม่เลว ตราบใดที่มันทำงานเพื่อแก้ปัญหาเฉพาะ 6 เดือนผ่านไปแล้วตั้งแต่ฉันโพสต์คำถามนี้และเราไม่เคยเสียใจที่ใช้วิธีนี้มาตั้งแต่
paulius_l

คำตอบ:


249

นี่เป็นวิธีที่ดีที่สุดที่ฉันพบว่าสนับสนุนวิธี GET เพิ่มเติมและสนับสนุนวิธี REST ปกติเช่นกัน เพิ่มเส้นทางต่อไปนี้ใน WebApiConfig ของคุณ:

routes.MapHttpRoute("DefaultApiWithId", "Api/{controller}/{id}", new { id = RouteParameter.Optional }, new { id = @"\d+" });
routes.MapHttpRoute("DefaultApiWithAction", "Api/{controller}/{action}");
routes.MapHttpRoute("DefaultApiGet", "Api/{controller}", new { action = "Get" }, new { httpMethod = new HttpMethodConstraint(HttpMethod.Get) });
routes.MapHttpRoute("DefaultApiPost", "Api/{controller}", new {action = "Post"}, new {httpMethod = new HttpMethodConstraint(HttpMethod.Post)});

ฉันยืนยันโซลูชันนี้ด้วยคลาสทดสอบด้านล่าง ฉันสามารถกดแต่ละวิธีในตัวควบคุมด้านล่างได้สำเร็จ:

public class TestController : ApiController
{
    public string Get()
    {
        return string.Empty;
    }

    public string Get(int id)
    {
        return string.Empty;
    }

    public string GetAll()
    {
        return string.Empty;
    }

    public void Post([FromBody]string value)
    {
    }

    public void Put(int id, [FromBody]string value)
    {
    }

    public void Delete(int id)
    {
    }
}

ฉันตรวจสอบแล้วว่ารองรับคำขอต่อไปนี้:

GET /Test
GET /Test/1
GET /Test/GetAll
POST /Test
PUT /Test/1
DELETE /Test/1

หมายเหตุว่าหากการดำเนินการ GET พิเศษของคุณไม่ได้ขึ้นต้นด้วย 'รับ' คุณอาจต้องการเพิ่มแอททริบิว HttpGet ลงในเมธอด


4
นี่เป็นคำตอบที่ยอดเยี่ยมและช่วยฉันได้มากกับคำถามอื่นที่เกี่ยวข้อง ขอบคุณ !!
Alfero Chingono

4
พยายามสิ่งนี้ - ไม่ทำงาน เส้นทางทั้งหมดจะถูกแมปแบบสุ่มกับวิธี GetBlah (long id) :(
BrainSlugs83

1
@ BrainSlugs83: มันขึ้นอยู่กับการสั่งซื้อ และคุณจะต้องการเพิ่ม (ไปยัง "withId" เมธอด), aconstraints: new{id=@"\d+"}
Eric Falsken

4
วิธีการเกี่ยวกับการเพิ่มวิธีอีกหนึ่งวิธี - รับ (int id, ชื่อสตริง) ... มันล้มเหลว
Anil Purswani

1
ฉันต้องเพิ่มเส้นทางพิเศษเช่นนี้routes.MapHttpRoute("DefaultApiPut", "Api/{controller}", new {action = "Put"}, new {httpMethod = new HttpMethodConstraint(HttpMethod.Put)});สำหรับPutวิธีการของฉันมิฉะนั้นมันก็ให้ฉัน 404
Syed Ali Taqi

57

ไปจากนี้:

config.Routes.MapHttpRoute("API Default", "api/{controller}/{id}",
            new { id = RouteParameter.Optional });

สำหรับสิ่งนี้:

config.Routes.MapHttpRoute("API Default", "api/{controller}/{action}/{id}",
            new { id = RouteParameter.Optional });

ดังนั้นตอนนี้คุณสามารถระบุการกระทำ (วิธี) ที่คุณต้องการส่งคำขอ HTTP ของคุณไป

การโพสต์ไปที่"http: // localhost: 8383 / api / Command / PostCreateUser"จะเรียกใช้:

public bool PostCreateUser(CreateUserCommand command)
{
    //* ... *//
    return true;
}

และโพสต์ไปที่"http: // localhost: 8383 / api / Command / PostMakeBooking"จะเรียกใช้:

public bool PostMakeBooking(MakeBookingCommand command)
{
    //* ... *//
    return true;
}

ฉันลองสิ่งนี้ในแอปพลิเคชันบริการ WEB API ที่โฮสต์ด้วยตนเองและทำงานได้อย่างมีเสน่ห์ :)


8
ขอบคุณสำหรับคำตอบที่เป็นประโยชน์ ฉันต้องการที่จะเพิ่มว่าถ้าคุณเริ่มต้นชื่อวิธีการของคุณด้วยรับโพสต์ ฯลฯ คำขอของคุณจะจับคู่กับวิธีการเหล่านั้นตามกริยา HTTP ที่ใช้ แต่คุณสามารถตั้งชื่อวิธีการของคุณได้จากนั้นตกแต่งด้วยแอตทริบิวต์[HttpGet], [HttpPost]และอื่น ๆ เพื่อแมปคำกริยากับเมธอด
indot_brad

โปรดดูคำถาม
Moeez

@DikaArtaKarunia ไม่มีปัญหาดีใจที่คำตอบของฉันยังคงใช้งานได้ 6 ปีต่อมา: D
uggeh

31

ฉันค้นหาคุณลักษณะที่จะสะอาดกว่าการใช้เพิ่มด้วยตนเองผ่านรหัส นี่คือตัวอย่างง่ายๆ

[RoutePrefix("api/example")]
public class ExampleController : ApiController
{
    [HttpGet]
    [Route("get1/{param1}")] //   /api/example/get1/1?param2=4
    public IHttpActionResult Get(int param1, int param2)
    {
        Object example = null;
        return Ok(example);
    }

}

คุณต้องการสิ่งนี้ใน webapiconfig ของคุณ

config.Routes.MapHttpRoute(
    name: "DefaultApi",
    routeTemplate: "api/{controller}/{id}",
    defaults: new { id = RouteParameter.Optional }
);

config.Routes.MapHttpRoute(
    name: "ActionApi",
    routeTemplate: "api/{controller}/{action}/{id}",
    defaults: new { id = RouteParameter.Optional }
);

บางลิงค์ที่ดี http://www.asp.net/web-api/overview/getting-started-with-aspnet-web-api/tutorial-your-first-web-api อัน นี้อธิบายการกำหนดเส้นทางได้ดีขึ้น http://www.asp.net/web-api/overview/web-api-routing-and-actions/routing-in-aspnet-web-api


3
ฉันต้องเพิ่มconfig.MapHttpAttributeRoutes();ไปยังของฉันWebApiConfig.csและGlobalConfiguration.Configuration.EnsureInitialized();ในตอนท้ายของWebApiApplication.Application_Start()วิธีการของฉันเพื่อรับคุณลักษณะเส้นทางในการทำงาน
Ergwun

@Ergwun ความคิดเห็นนี้ช่วยฉันได้มาก เพียงเพื่อเพิ่มมันconfig.MapHttpAttributeRoutes();ต้องการที่จะปรากฏขึ้นก่อนการทำแผนที่เส้นทาง (เช่นก่อนconfig.Routes.MappHttpRoute(....
ฟิลิปฟอร์ด

11

คุณต้องกำหนดเส้นทางเพิ่มเติมใน global.asax.cs ดังนี้:

routes.MapHttpRoute(
    name: "Api with action",
    routeTemplate: "api/{controller}/{action}/{id}",
    defaults: new { id = RouteParameter.Optional }
);

routes.MapHttpRoute(
    name: "DefaultApi",
    routeTemplate: "api/{controller}/{id}",
    defaults: new { id = RouteParameter.Optional }
);

5
ใช่มันเป็นความจริง แต่มันจะดีจริง ๆ ที่เห็นตัวอย่างของเส้นทางเหล่านั้น มันจะทำให้คำตอบนี้มีคุณค่ามากขึ้นกับชุมชน (และคุณจะได้รับ +1 จากฉัน :)
อรัญมัลฮอลแลนด์

คุณสามารถอ่านตัวอย่างได้ที่นี่ - stackoverflow.com/questions/11407267/…
Tom Kerkhove

2
ทางออกที่แท้จริงน่าจะดีกว่า
Goblins มากมายดังนั้น

6

ด้วย Web Api 2 ที่ใหม่กว่ามันง่ายกว่าที่จะมีวิธีการหลายวิธี

หากพารามิเตอร์ที่ส่งผ่านไปยังGETเมธอดนั้นแตกต่างกันพอสำหรับระบบการจัดเส้นทางของแอ็ตทริบิวต์เพื่อแยกความแตกต่างของชนิดตามที่เป็นกรณีกับints และGuids คุณสามารถระบุชนิดที่คาดไว้ในแอ[Route...]ททริบิวต์

ตัวอย่างเช่น -

[RoutePrefix("api/values")]
public class ValuesController : ApiController
{

    // GET api/values/7
    [Route("{id:int}")]
    public string Get(int id)
    {
       return $"You entered an int - {id}";
    }

    // GET api/values/AAC1FB7B-978B-4C39-A90D-271A031BFE5D
    [Route("{id:Guid}")]
    public string Get(Guid id)
    {
       return $"You entered a GUID - {id}";
    }
} 

สำหรับรายละเอียดเพิ่มเติมเกี่ยวกับวิธีการนี้ดูที่นี่http://nodogmablog.bryanhogan.net/2017/02/web-api-2-controller-with-multiple-get-methods-part-2

อีกทางเลือกหนึ่งคือให้GETวิธีการต่าง ๆ ในเส้นทาง

    [RoutePrefix("api/values")]
    public class ValuesController : ApiController
    {
        public string Get()
        {
            return "simple get";
        }

        [Route("geta")]
        public string GetA()
        {
            return "A";
        }

        [Route("getb")]
        public string GetB()
        {
            return "B";
        }
   }

ดูที่นี่สำหรับรายละเอียดเพิ่มเติม - http://nodogmablog.bryanhogan.net/2016/10/web-api-2-controller-with-multiple-get-methods/


5

ใน ASP.NET Core 2.0 คุณสามารถเพิ่มแอตทริบิวต์Routeให้กับคอนโทรลเลอร์ได้:

[Route("api/[controller]/[action]")]
public class SomeController : Controller
{
    public SomeValue GetItems(CustomParam parameter) { ... }

    public SomeValue GetChildItems(CustomParam parameter, SomeObject parent) { ... }
}

4

ฉันกำลังพยายามใช้การกำหนดเส้นทางแอตทริบิวต์ Web Api 2 เพื่ออนุญาตให้ใช้หลายวิธีและฉันได้รวมคำแนะนำที่เป็นประโยชน์จากคำตอบก่อนหน้านี้ แต่ในคอนโทรลเลอร์ฉันได้ตกแต่งวิธี "พิเศษ" เท่านั้น (ตัวอย่าง):

[Route( "special/{id}" )]
public IHttpActionResult GetSomethingSpecial( string id ) {

... โดยไม่ต้องวาง [RoutePrefix] ไว้ที่ด้านบนของคอนโทรลเลอร์ด้วย:

[RoutePrefix("api/values")]
public class ValuesController : ApiController

ฉันได้รับข้อผิดพลาดที่ระบุว่าไม่พบเส้นทางที่ตรงกับ URI ที่ส่งมา เมื่อฉันมีทั้ง [Route] ตกแต่งวิธีการรวมทั้ง [RoutePrefix] เพื่อตกแต่งคอนโทรลเลอร์โดยรวมแล้วมันก็ใช้งานได้


3

ฉันไม่แน่ใจว่าคุณได้พบคำตอบแล้วหรือไม่ แต่ฉันทำอย่างนี้แล้วก็ใช้งานได้

public IEnumerable<string> Get()
{
    return new string[] { "value1", "value2" };
}

// GET /api/values/5
public string Get(int id)
{
    return "value";
}

// GET /api/values/5
[HttpGet]
public string GetByFamily()
{
    return "Family value";
}

ขณะนี้อยู่ใน global.asx

routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

routes.MapHttpRoute(
    name: "DefaultApi2",
    routeTemplate: "api/{controller}/{action}",
    defaults: new { id = RouteParameter.Optional }
);

routes.MapHttpRoute(
    name: "DefaultApi",
    routeTemplate: "api/{controller}/{id}",
    defaults: new { id = RouteParameter.Optional }
);

routes.MapRoute(
    name: "Default",
    url: "{controller}/{action}/{id}",
    defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);

3

คุณลองเปลี่ยนมาใช้ WebInvokeAttribute แล้วตั้งค่า Method เป็น "GET" หรือไม่?

ฉันเชื่อว่าฉันมีปัญหาที่คล้ายกันและเปลี่ยนเป็นการบอกวิธีการอย่างชัดเจน (GET / PUT / POST / DELETE) ซึ่งส่วนใหญ่คาดว่าเป็นวิธีการของฉัน

public class SomeController : ApiController
{
    [WebInvoke(UriTemplate = "{itemSource}/Items"), Method="GET"]
    public SomeValue GetItems(CustomParam parameter) { ... }

    [WebInvoke(UriTemplate = "{itemSource}/Items/{parent}", Method = "GET")]
    public SomeValue GetChildItems(CustomParam parameter, SomeObject parent) { ... }
}

WebGet ควรจัดการกับมัน แต่ฉันเห็นว่ามันมีปัญหาบางอย่างกับหลาย ๆ รับน้อยลงหลาย ๆ เท่ารับผลตอบแทนประเภทเดียวกัน

[แก้ไข: ไม่มีสิ่งใดถูกต้องกับพระอาทิตย์ตกของ WCF WebAPI และการย้ายไปยัง ASP.Net WebAPI บนสแต็ก MVC]


1
ฉันขอโทษฉันลืมที่จะพูดถึงว่าฉันกำลังย้ายรหัสไปยัง ASP.NET Web API ตั้งแต่ WCF Web API ถูกยกเลิก ฉันแก้ไขโพสต์ ขอบคุณ.
paulius_l

2
**Add Route function to direct the routine what you want**
    public class SomeController : ApiController
    {
        [HttpGet()]
        [Route("GetItems")]
        public SomeValue GetItems(CustomParam parameter) { ... }

        [HttpGet()]
        [Route("GetChildItems")]
        public SomeValue GetChildItems(CustomParam parameter, SomeObject parent) { ... }
    }

ยินดีต้อนรับสู่ Stack Overflow! โปรดแก้ไขคำตอบของคุณเพื่อรวมคำอธิบายสำหรับรหัสของคุณรวมถึงคำอธิบายว่ามันแตกต่างจากคำตอบอื่น ๆ อีกสิบสี่คำที่นี่หรือไม่ คำถามนี้มีอายุเกือบแปดปีแล้วและมีคำตอบที่ได้รับการยอมรับและมีคำอธิบายที่ดี หากไม่มีคำอธิบายของคุณก็น่าจะถูกลดระดับหรือลบออก การมีคำอธิบายนั้นจะช่วยให้คำตอบของคุณตรงกับคำถามนี้
Das_Geek

1
โดยส่วนตัว (ฉันรู้ว่าคำแนะนำ SOs ใด) สำหรับคำถามนี้ชัดเจน / ขั้นพื้นฐานฉันเองค่อนข้างจะค่อนข้างมีคำตอบรหัสบริสุทธิ์ ฉันไม่ต้องการที่จะอ่านจำนวนมากของคำอธิบายที่ฉันอยากให้เป็นประโยชน์ได้อย่างรวดเร็วซอฟแวร์การทำงาน +1
MemeDeveloper

2

ทางเลือกที่ขี้เกียจ / รีบร้อน (Dotnet Core 2.2):

[HttpGet("method1-{item}")]
public string Method1(var item) { 
return "hello" + item;}

[HttpGet("method2-{item}")]
public string Method2(var item) { 
return "world" + item;}

โทรหาพวกเขา:

localhost: 5000 / API / controllername / method1-42

"hello42"

localhost: 5000 / API / controllername / method2-99

"world99"


0

ไม่มีตัวอย่างข้างต้นที่เหมาะกับความต้องการส่วนตัวของฉัน ด้านล่างเป็นสิ่งที่ฉันทำ

 public class ContainsConstraint : IHttpRouteConstraint
{       
    public string[] array { get; set; }
    public bool match { get; set; }

    /// <summary>
    /// Check if param contains any of values listed in array.
    /// </summary>
    /// <param name="param">The param to test.</param>
    /// <param name="array">The items to compare against.</param>
    /// <param name="match">Whether we are matching or NOT matching.</param>
    public ContainsConstraint(string[] array, bool match)
    {

        this.array = array;
        this.match = match;
    }

    public bool Match(System.Net.Http.HttpRequestMessage request, IHttpRoute route, string parameterName, IDictionary<string, object> values, HttpRouteDirection routeDirection)
    {
        if (values == null) // shouldn't ever hit this.                   
            return true;

        if (!values.ContainsKey(parameterName)) // make sure the parameter is there.
            return true;

        if (string.IsNullOrEmpty(values[parameterName].ToString())) // if the param key is empty in this case "action" add the method so it doesn't hit other methods like "GetStatus"
            values[parameterName] = request.Method.ToString();

        bool contains = array.Contains(values[parameterName]); // this is an extension but all we are doing here is check if string array contains value you can create exten like this or use LINQ or whatever u like.

        if (contains == match) // checking if we want it to match or we don't want it to match
            return true;
        return false;             

    }

วิธีใช้ด้านบนในการใช้เส้นทางของคุณ:

config.Routes.MapHttpRoute("Default", "{controller}/{action}/{id}", new { action = RouteParameter.Optional, id = RouteParameter.Optional}, new { action = new ContainsConstraint( new string[] { "GET", "PUT", "DELETE", "POST" }, true) });

สิ่งที่เกิดขึ้นคือชนิดข้อ จำกัด ของการปลอมในวิธีการเพื่อให้เส้นทางนี้ตรงกับวิธีการ GET, POST, PUT และ DELETE เริ่มต้นเท่านั้น "ความจริง" ที่มีบอกว่าเราต้องการตรวจสอบการจับคู่ของรายการในอาร์เรย์ หากเป็นเท็จคุณจะบอกว่าไม่รวมเส้นทางเหล่านั้นใน strYou สามารถใช้เส้นทางเหนือวิธีเริ่มต้นนี้เช่น:

config.Routes.MapHttpRoute("GetStatus", "{controller}/status/{status}", new { action = "GetStatus" });

ในด้านบนนั้นเป็นหลักมองหา URL => ต่อไปนี้http://www.domain.com/Account/Status/Activeหรืออะไรทำนองนั้น

เหนือสิ่งอื่นใดฉันไม่แน่ใจว่าฉันบ้าเกินไป ในตอนท้ายของวันที่ควรจะเป็นต่อทรัพยากร แต่ฉันเห็นความจำเป็นในการแมป URL ที่เป็นมิตรด้วยเหตุผลหลายประการ ฉันรู้สึกค่อนข้างมั่นใจว่า Web Api วิวัฒนาการจะมีบทบัญญัติบางอย่าง ถ้าเวลาฉันจะสร้างทางออกที่ถาวรและโพสต์


คุณสามารถใช้new System.Web.Http.Routing.HttpMethodConstraint(HttpMethod.Get, HttpMethod.Post, HttpMethod.Put, HttpMethod.Delete) แทน
abatishchev

0

ไม่สามารถแก้ไขปัญหาการกำหนดเส้นทางใด ๆ ข้างต้น - ไวยากรณ์บางส่วนดูเหมือนว่าจะมีการเปลี่ยนแปลงและฉันยังใหม่กับ MVC - ในเวลาสั้น ๆ แม้ว่าฉันจะรวบรวมแฮ็ค (และเรียบง่าย) ที่น่ากลัวจริงๆซึ่งจะทำให้ฉัน โดยตอนนี้ - หมายเหตุสิ่งนี้แทนที่เมธอด "public MyObject GetMyObjects (long id)" - เราเปลี่ยนชนิดของ "id" เป็นสตริงและเปลี่ยนชนิดส่งคืนเป็นออบเจ็กต์

// GET api/MyObjects/5
// GET api/MyObjects/function
public object GetMyObjects(string id)
{
    id = (id ?? "").Trim();

    // Check to see if "id" is equal to a "command" we support
    // and return alternate data.

    if (string.Equals(id, "count", StringComparison.OrdinalIgnoreCase))
    {
        return db.MyObjects.LongCount();
    }

    // We now return you back to your regularly scheduled
    // web service handler (more or less)

    var myObject = db.MyObjects.Find(long.Parse(id));
    if (myObject == null)
    {
        throw new HttpResponseException
        (
            Request.CreateResponse(HttpStatusCode.NotFound)
        );
    }

    return myObject;
}

0

หากคุณมี Action หลาย ๆ ไฟล์ภายในไฟล์เดียวกันให้ส่งอาร์กิวเมนต์เดียวกันเช่น Id ไปที่ Action ทั้งหมด นี่เป็นเพราะการกระทำสามารถระบุ ID ได้ดังนั้นแทนที่จะให้ชื่อใด ๆ เพื่อโต้แย้งเพียงประกาศรหัสเช่นนี้


[httpget]
[ActionName("firstAction")] firstAction(string Id)
{.....
.....
}
[httpget]
[ActionName("secondAction")] secondAction(Int Id)
{.....
.....
}
//Now go to webroute.config file under App-start folder and add following
routes.MapHttpRoute(
name: "firstAction",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);

routes.MapHttpRoute(
name: "secondAction",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);

URL ดูเหมือนจะดูแต่ละฟังก์ชั่นในเบราว์เซอร์อย่างไร
Si8

0

ทางเลือกง่าย ๆ

เพียงใช้สตริงแบบสอบถาม

เส้นทาง

config.Routes.MapHttpRoute(
    name: "DefaultApi",
    routeTemplate: "api/{controller}/{id}",
    defaults: new { id = RouteParameter.Optional }
);

ตัวควบคุม

public class TestController : ApiController
{
    public IEnumerable<SomeViewModel> Get()
    {
    }

    public SomeViewModel GetById(int objectId)
    {
    }
}

การร้องขอ

GET /Test
GET /Test?objectId=1

บันทึก

โปรดทราบว่าพารามิเตอร์สตริงการสืบค้นไม่ควรเป็น "id" หรือพารามิเตอร์ใด ๆ ที่อยู่ในเส้นทางที่กำหนดค่าไว้


-1

แก้ไขWebApiConfigและเพิ่มที่ส่วนท้ายของ Routes.MapHttpRoute ดังนี้:

config.Routes.MapHttpRoute(
                name: "ServiceApi",
                routeTemplate: "api/Service/{action}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );

จากนั้นสร้างตัวควบคุมดังนี้:

public class ServiceController : ApiController
{
        [HttpGet]
        public string Get(int id)
        {
            return "object of id id";
        }
        [HttpGet]
        public IQueryable<DropDownModel> DropDowEmpresa()
        {
            return db.Empresa.Where(x => x.Activo == true).Select(y =>
                  new DropDownModel
                  {
                      Id = y.Id,
                      Value = y.Nombre,
                  });
        }

        [HttpGet]
        public IQueryable<DropDownModel> DropDowTipoContacto()
        {
            return db.TipoContacto.Select(y =>
                  new DropDownModel
                  {
                      Id = y.Id,
                      Value = y.Nombre,
                  });
        }

        [HttpGet]
        public string FindProductsByName()
        {
            return "FindProductsByName";
        }
}

นี่คือวิธีที่ฉันแก้ไขมัน ฉันหวังว่ามันจะช่วยให้ใครบางคน

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.