คุณสามารถโอเวอร์โหลดคอนโทรลเลอร์ใน ASP.NET MVC ได้หรือไม่?


327

ฉันอยากรู้ว่าคุณสามารถโอเวอร์โหลดวิธีการควบคุมใน ASP.NET MVC ได้หรือไม่ เมื่อใดก็ตามที่ฉันพยายามฉันได้รับข้อผิดพลาดด้านล่าง ทั้งสองวิธียอมรับข้อโต้แย้งที่แตกต่างกัน นี่เป็นสิ่งที่ไม่สามารถทำได้ใช่ไหม

คำขอปัจจุบันสำหรับการกระทำ 'MyMethod' ในประเภทตัวควบคุม 'MyController' นั้นไม่ชัดเจนระหว่างวิธีการดำเนินการต่อไปนี้:


10
@andy ของมันเหมือนกันสำหรับ MVC 4 รวม :)
basarat

10
และเช่นเดียวกันสำหรับ mvc 5
DhruvJoshi

10
และเช่นเดียวกันสำหรับ MVC 6
Imad

7
และเช่นเดียวกันสำหรับ MVC Core 1.1
kall2sollies

7
และเช่นเดียวกันสำหรับ MVC Core 2.0
Guilherme

คำตอบ:


201

คุณสามารถใช้แอททริบิวท์ได้หากคุณต้องการให้โค้ดของคุณทำงานหนักเกินไป

[ActionName("MyOverloadedName")]

แต่คุณจะต้องใช้ชื่อการกระทำที่แตกต่างกันสำหรับวิธี http เดียวกัน (อย่างที่คนอื่นพูด) ดังนั้นมันเป็นเพียงความหมาย ณ จุดนั้น คุณค่อนข้างจะมีชื่อในรหัสหรือคุณสมบัติของคุณหรือไม่

Phil มีบทความที่เกี่ยวข้องกับสิ่งนี้: http://haacked.com/archive/2008/08/29/how-a-method-becomes-an-action.aspx


5
ข้อเสียเปรียบหลักของการใช้สิ่งนี้และการกระทำที่มากเกินไปของคุณคือการไม่สามารถแสดงผลด้วยไฟล์มุมมองเดียวกันได้อีกต่อไป
Jeff Martin

66
ที่จริงแล้วมันยังคงสามารถแสดงไฟล์มุมมองเดียวกัน return View();คุณเพียงแค่ต้องระบุชื่อของมุมมองแทนการโทรสุ่มสี่สุ่มห้า ตัวอย่างเช่นreturn View("MyOverloadedName");.
EAMann

1
@JD แต่ Microsoft บอกว่า .. วิธีการที่ใช้เป็นตัวควบคุมการกระทำไม่สามารถโหลดได้มากเกินไป .. คุณสามารถดูได้ที่นี่ .. asp.net/mvc/tutorials/controllers-and-routing/
himanshupareek66

@EAMann Nice ฉันมักจะกำหนดเส้นทางทั้งหมดสำหรับการดูจนถึงตอนนี้
Alexander Derck

69

ใช่. ฉันสามารถทำสิ่งนี้ได้โดยการตั้งค่าHttpGet/ HttpPost(หรือAcceptVerbsแอตทริบิวต์ที่เทียบเท่า) สำหรับวิธีการควบคุมแต่ละวิธีเป็นสิ่งที่แตกต่างกันเช่นHttpGetหรือHttpPostแต่ไม่ใช่ทั้งสองอย่าง วิธีนั้นสามารถบอกได้ตามประเภทของคำขอที่ใช้วิธีการ

[HttpGet]
public ActionResult Show()
{
   ...
}

[HttpPost]
public ActionResult Show( string userName )
{
   ...
}

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


1
ด้วย MVC2 และมากกว่าหนึ่งสามารถใช้คุณลักษณะ HttpPost / HttpGet
yoel halb

@yohal ใช่ว่าจะเป็นวิธีที่ได้รับการยอมรับในขณะนี้ถ้าคุณไม่จำเป็นต้องรองรับคำกริยาหลายคำ
tvanfosson

3
เพียงระวังที่จะไม่ใช้สิ่งนี้เพื่อละเมิดหลักการของ REST
Fred

1
ค่อนข้างแน่ใจว่าวิธีนี้ใช้งานได้เพียงเพราะShow()วิธีการของคุณมีลายเซ็นที่แตกต่างกัน หากและเมื่อคุณต้องการส่งข้อมูลไปยังรุ่นรับรุ่นรับและโพสต์ของคุณจะลงท้ายด้วยลายเซ็นเดียวกันและคุณต้องมีActionNameแอตทริบิวต์หรือหนึ่งในวิธีแก้ไขอื่น ๆ ที่กล่าวถึงในโพสต์นี้
Scott Fraley

1
@ ScottK.Fraley นั่นเป็นเรื่องจริง ActionNameAttributeหากพวกเขาต้องการลายเซ็นเดียวกับที่คุณจะต้องตั้งชื่อพวกเขาแตกต่างกันและใช้ ในทางปฏิบัติฉันไม่ค่อยพบว่าเป็นเช่นนั้น
tvanfosson

42

นี่คือสิ่งอื่นที่คุณสามารถทำได้ ... คุณต้องการวิธีการที่สามารถมีพารามิเตอร์ได้

ลองทำไมไม่ลอง ...

public ActionResult Show( string username = null )
{
   ...
}

สิ่งนี้ใช้ได้กับฉัน ... และในวิธีนี้คุณสามารถทดสอบเพื่อดูว่าคุณมีพารามิเตอร์ขาเข้าหรือไม่


อัปเดตเพื่อลบไวยากรณ์ nullable ที่ไม่ถูกต้องบนสตริงและใช้ค่าพารามิเตอร์เริ่มต้น


6
( stringไม่สามารถเป็นโมฆะได้)
Josh M.

23
สตริงสามารถเป็นโมฆะ ในความเป็นจริงมันเป็นโมฆะเพียงไม่ต้องการ '?'
ProfK

9
@ProfK - ไม่สตริงเป็นประเภทข้อมูลอ้างอิงซึ่งอาจเป็นค่าว่าง ไม่ใช่ "nullable" Nullable หมายความว่าคุณกำลังใช้ Nullable <T> (เช่น T?) ประเด็นของ Josh คือคุณไม่สามารถใส่ได้? หลังจากสตริงเนื่องจากไม่ใช่ประเภทค่าและ Nullable <T> ยอมรับเฉพาะประเภทค่าเท่านั้น
Erik Funkenbusch

4
ฉันสุ่มพบทางกลับไปที่คำถามนี้จากนั้นฉันก็รู้ว่าฉันโพสต์ความคิดเห็นด้านบน ไม่มีความทรงจำเกี่ยวกับเรื่องนี้ ... แปลก! มันยังคงเป็นจริงที่stringไม่สามารถnullable; แต่มันสามารถเป็นnull! ทั้งสองวิธีที่ฉันโพสต์ความคิดเห็นเริ่มต้นโดยไม่มีความจริงใจ
Josh M.

20

ไม่ไม่และไม่ไปและลองใช้รหัสควบคุมด้านล่างซึ่งเรามี "LoadCustomer" มากเกินไป

public class CustomerController : Controller
    {
        //
        // GET: /Customer/

        public ActionResult LoadCustomer()
        {
            return Content("LoadCustomer");
        }
        public ActionResult LoadCustomer(string str)
        {
            return Content("LoadCustomer with a string");
        }
    }

หากคุณพยายามเรียกใช้การกระทำ "LoadCustomer" คุณจะได้รับข้อผิดพลาดดังแสดงในรูปด้านล่าง

ป้อนคำอธิบายรูปภาพที่นี่

ความแตกต่างเป็นส่วนหนึ่งของการเขียนโปรแกรม C # ในขณะที่ HTTP เป็นโปรโตคอล HTTP ไม่เข้าใจความหลากหลาย HTTP ทำงานบนแนวคิดหรือ URL และ URL สามารถมีชื่อเฉพาะได้ ดังนั้น HTTP ไม่ได้ใช้ความหลากหลาย

เพื่อแก้ไขปัญหาเดียวกันเราจำเป็นต้องใช้แอตทริบิวต์ "ActionName"

public class CustomerController : Controller
    {
        //
        // GET: /Customer/

        public ActionResult LoadCustomer()
        {
            return Content("LoadCustomer");
        }

        [ActionName("LoadCustomerbyName")]
        public ActionResult LoadCustomer(string str)
        {
            return Content("LoadCustomer with a string");
        }
    }

ดังนั้นหากคุณโทรไปที่ URL "ลูกค้า / LoadCustomer" การกระทำ "LoadCustomer" จะถูกเรียกใช้และด้วยโครงสร้าง URL "ลูกค้า / LoadCustomerByName" "LoadCustomer (สตริง str)" จะถูกเรียกใช้

ป้อนคำอธิบายรูปภาพที่นี่

ป้อนคำอธิบายรูปภาพที่นี่

คำตอบข้างต้นฉันได้นำมาจากบทความ codeproject นี้ -> การกระทำเกินพิกัด MVC Action


ขอบคุณสำหรับสิ่งนี้. ฉันเดาว่าคุณอาจใช้ชื่อการกระทำที่แตกต่างจากจุดเริ่มต้นแทนที่จะใช้แอตทริบิวต์
ด่าน

1
@Dan แต่จากนั้นเราไม่ได้มีความหลากหลายในด้าน C #
Shivprasad Koirala

คุณถูกต้องไม่มีวิธีการควบคุมการบรรทุกเกินพิกัด แต่ไม่มีอะไรเกี่ยวข้องกับ HTTP
Chalky

ขอบคุณสำหรับการชี้แจง +1 ควรจะคิด HTTP มากกว่านี้ไม่ใช่ C # ไม่มีเหตุผลที่จะเข้าใกล้การกระทำด้วยกลยุทธ์ OO

15

เพื่อเอาชนะปัญหานี้คุณสามารถเขียนสิ่งActionMethodSelectorAttributeที่ตรวจสอบMethodInfoสำหรับแต่ละการกระทำและเปรียบเทียบกับค่าแบบฟอร์มที่โพสต์แล้วปฏิเสธวิธีการใด ๆ ที่ค่าของแบบฟอร์มไม่ตรงกัน (ยกเว้นชื่อปุ่มแน่นอน)

นี่คือตัวอย่าง: - http://blog.abodit.com/2010/02/asp-net-mvc-ambiguous-match/

แต่นี่ไม่ใช่ความคิดที่ดี


@Cerbrus เพราะมันเป็นแฮ็คที่น่ากลัวและคนต่อไปที่ดูรหัสคอนโทรลเลอร์ของคุณจะสับสนด้วยวิธีการที่ไม่ได้มาตรฐาน
เอียนเมอร์เซอร์

เฮ้ยุติธรรมพอ
Cerbrus

14

เท่าที่ฉันรู้คุณสามารถมีวิธีการเดียวกันเมื่อใช้วิธีการ http ที่แตกต่างกัน

กล่าวคือ

[AcceptVerbs("GET")]
public ActionResult MyAction()
{

}

[AcceptVerbs("POST")]
public ActionResult MyAction(FormResult fm)
{

}

2
การตกแต่งไม่มีอะไรเกี่ยวข้องกับการโอเวอร์โหลด เป็นรายการพารามิเตอร์ที่อนุญาตการโอเวอร์โหลด
Sky Sanders

@SkySanders ฉันไม่เห็นด้วยการโหลดมากเกินไปตามพารามิเตอร์ไม่ทำงานในวิธีการควบคุม MVC - คุณมีตัวอย่างการทำงานหรือไม่ ไชโย
Chalky

ใช้แอตทริบิวต์แทน[HttpPost] [AcceptVerbs("POST")]
Fred

9

ฉันได้รับสิ่งนี้ด้วยความช่วยเหลือของการกำหนดเส้นทางแอตทริบิวต์ใน MVC5 เป็นที่ยอมรับว่าฉันใหม่กับ MVC ที่มาจากทศวรรษของการพัฒนาเว็บโดยใช้ WebForms แต่สิ่งต่อไปนี้ได้ผลสำหรับฉัน ซึ่งแตกต่างจากคำตอบที่ยอมรับนี้ช่วยให้การกระทำเกินพิกัดทั้งหมดจะแสดงผลโดยไฟล์มุมมองเดียวกัน

ขั้นแรกให้เปิดใช้งานการกำหนดเส้นทางแอตทริบิวต์ใน App_Start / RouteConfig.cs

public class RouteConfig
{
    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        routes.MapMvcAttributeRoutes();

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

เลือกตกแต่งคลาสคอนโทรลเลอร์ของคุณด้วยคำนำหน้าเส้นทางเริ่มต้น

[RoutePrefix("Returns")]
public class ReturnsController : BaseController
{
    //.......

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

[HttpGet]
// Returns
public ActionResult Index()
{
    //.....
}

[HttpGet]
[Route("View")]
// Returns/View
public ActionResult View()
{
    // I wouldn't really do this but it proves the concept.
    int id = 7026;
    return View(id);
}

[HttpGet]
[Route("View/{id:int}")]
// Returns/View/7003
public ActionResult View(int id)
{
    //.....
}

[HttpGet]
[Route("View/{id:Guid}")]
// Returns/View/99300046-0ba4-47db-81bf-ba6e3ac3cf01
public ActionResult View(Guid id)
{
    //.....
}

หวังว่าสิ่งนี้จะช่วยได้และไม่ได้นำใครบางคนสู่เส้นทางที่ผิด :-)


เยี่ยมมาก! ฉันเพิ่งพบปัญหานี้คุณช่วยฉัน! ฉันมี "x" ปีกับ WebForms - ดังนั้นจึงเป็นช่วงการเรียนรู้อย่างมาก ไม่สามารถรับงานที่ไม่มี MVC ได้วันนี้ฮ่า ๆ ๆ
Tez Wingfield

4

คุณสามารถใช้ซิงเกิ้ลActionResultเพื่อจัดการกับทั้งสองPostและGet:

public ActionResult Example() {
   if (Request.HttpMethod.ToUpperInvariant() == "GET") {
    // GET
   }
   else if (Request.HttpMethod.ToUpperInvariant() == "POST") {
     // Post  
   }
}

มีประโยชน์ถ้าคุณGetและPostวิธีการมีลายเซ็นตรงกัน


1
หืมมมมมมมมมมชอบอีกครั้ง แต่คราวนี้เป็นรูปสี่เหลี่ยมจัตุรัส ทำไมไม่เพียงใช้แอตทริบิวต์ [HttpPost / Get]
SOReader

มันใช้เวลาสักพัก แต่ฉันคิดว่าฉันทำอย่างนี้เพราะ MVC ไม่ได้แยกความแตกต่างระหว่างสองวิธีที่แตกต่างกัน ผมใช้ HttpPost แอตทริบิวต์แม้ว่าผมไม่ได้วาง HTTPGET กับวิธีการอื่น ๆ ..
DevDave

@DevDave เช่นเดียวกับการบันทึกทั้งสองวิธีตรวจสอบให้แน่ใจว่าคุณกำลังใช้แอตทริบิวต์จาก system.web.mvc - และไม่ใช่วิธีจาก system.web.http!
Chalky

4

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

หากมีความเข้าใจในการกำหนดเส้นทางนอกเหนือจากรูปแบบเส้นทางเริ่มต้น {controller} / {action} / {id} อย่างง่ายอาจเป็นที่ชัดเจนว่าการกระทำของตัวควบคุมสามารถแมปได้โดยใช้รูปแบบที่ไม่ซ้ำกัน มีคนที่พูดถึง polymorphism และพูดว่า: "HTTP ไม่เข้าใจ polymorphism" แต่การกำหนดเส้นทางไม่เกี่ยวข้องกับ HTTP มันเป็นเพียงกลไกสำหรับการจับคู่รูปแบบสตริง

วิธีที่ดีที่สุดในการทำให้งานนี้คือการใช้แอตทริบิวต์การกำหนดเส้นทางตัวอย่างเช่น:

[RoutePrefix("cars/{country:length(3)}")]
public class CarHireController
{
    [Route("{location}/{page:int=1}", Name = "CarHireLocation")]
    public ActionResult Index(string country, string location, int page)
    {
        return Index(country, location, null, page);
    }

    [Route("{location}/{subLocation}/{page:int=1}", Name = "CarHireSubLocation")]
    public ActionResult Index(string country, string location, string subLocation, int page)
    {
        //The main work goes here
    }
}

การกระทำเหล่านี้จะดูแล URL ที่ชอบ/cars/usa/new-yorkและ/cars/usa/texas/dallasซึ่งจะจับคู่กับการกระทำดัชนีครั้งแรกและครั้งที่สองตามลำดับ

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

ประโยชน์ของรูปแบบการกำหนดเส้นทางเริ่มต้นคือสร้างเส้นทางที่ไม่ซ้ำกันโดยอัตโนมัติ สิ่งนี้ถูกบังคับใช้โดยคอมไพเลอร์เนื่องจาก URL จะตรงกับชนิดของตัวควบคุมและสมาชิกที่ไม่ซ้ำกัน การหมุนรูปแบบเส้นทางของคุณจะต้องใช้ความคิดอย่างรอบคอบเพื่อให้แน่ใจว่ามีเอกลักษณ์และใช้งานได้

หมายเหตุสำคัญข้อเสียเปรียบประการหนึ่งคือการใช้การกำหนดเส้นทางเพื่อสร้าง URL สำหรับการดำเนินการที่มากเกินไปจะไม่ทำงานเมื่อใช้ชื่อการกระทำเช่นเมื่อใช้ UrlHelper.Action แต่มันจะใช้งานได้หากมีการใช้เส้นทางที่มีชื่อเช่น UrlHelper.RouteUrl และการใช้เส้นทางที่มีชื่อนั้นเป็นไปตามแหล่งที่ได้รับการยอมรับอย่างดีวิธีที่จะเดินทางต่อไป ( http://haacked.com/archive/2010/11/21/named-routes-to-the-rescue.aspx/ )

โชคดี!


3

คุณสามารถใช้ [ActionName ("NewActionName")] เพื่อใช้วิธีการเดียวกันกับชื่ออื่น:

public class HomeController : Controller
{
    public ActionResult GetEmpName()
    {
        return Content("This is the test Message");
    }

    [ActionName("GetEmpWithCode")]
    public ActionResult GetEmpName(string EmpCode)
    {
        return Content("This is the test Messagewith Overloaded");
    }
}

2

ฉันต้องการโอเวอร์โหลดสำหรับ:

public ActionResult Index(string i);
public ActionResult Index(int groupId, int itemId);

มีข้อโต้แย้งไม่มากพอที่ฉันได้ทำสิ่งนี้:

public ActionResult Index(string i, int? groupId, int? itemId)
{
    if (!string.IsNullOrWhitespace(i))
    {
        // parse i for the id
    }
    else if (groupId.HasValue && itemId.HasValue)
    {
        // use groupId and itemId for the id
    }
}

มันไม่ใช่ทางออกที่สมบูรณ์แบบโดยเฉพาะถ้าคุณมีข้อโต้แย้งมากมาย แต่มันใช้ได้ดีสำหรับฉัน


1

ฉันประสบปัญหาเดียวกันในใบสมัครของฉันด้วย หากไม่มีข้อมูลวิธีการใด ๆ Modifiyig ฉันได้ให้ [ActionName ("SomeMeaningfulName")] บน Action head ปัญหาได้รับการแก้ไข

[ActionName("_EmployeeDetailsByModel")]
        public PartialViewResult _EmployeeDetails(Employee model)
        {
            // Some Operation                
                return PartialView(model);
            }
        }

[ActionName("_EmployeeDetailsByModelWithPagination")]
        public PartialViewResult _EmployeeDetails(Employee model,int Page,int PageSize)
        {

                // Some Operation
                return PartialView(model);

        }

0

สร้างวิธีการพื้นฐานเป็นเสมือน

public virtual ActionResult Index()

สร้างวิธีการแทนที่เป็นแทนที่

public override ActionResult Index()

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


2
คุณอาจเข้าใจผิดคำถาม OP กำลังถามเกี่ยวกับการโหลดเมธอดมากเกินไปในคอนโทรลเลอร์เดียวกันไม่ใช่ลบล้างมันในคลาสที่ได้รับมา
Ace

@Andiih: จะเกิดอะไรขึ้นหากทั้งสองวิธีอยู่ในคอนโทรลเลอร์เดียวกัน
Dharmik Bhandari

0

ฉันชอบคำตอบนี้โพสต์ในหัวข้ออื่น

ส่วนใหญ่จะใช้หากคุณสืบทอดจากคอนโทรลเลอร์อื่นและต้องการแทนที่การ acction จากคอนโทรลเลอร์พื้นฐาน

ASP.NET MVC - การเอาชนะการกระทำที่มีพารามิเตอร์ต่างกัน


0

มีลายเซ็นสาธารณะเดียวเท่านั้นที่ได้รับอนุญาตสำหรับแต่ละวิธีการควบคุม หากคุณพยายามใช้งานมากเกินไปมันจะรวบรวม แต่คุณได้รับข้อผิดพลาดขณะทำงานที่คุณพบ

หากคุณไม่ต้องการใช้คำกริยาที่ต่างกัน (เช่น[HttpGet]และ[HttpPost]คุณลักษณะ) เพื่อแยกแยะวิธีโอเวอร์โหลด (ซึ่งจะทำงาน) หรือเปลี่ยนเส้นทางแล้วสิ่งที่เหลืออยู่คือคุณสามารถให้วิธีอื่นด้วยชื่ออื่นหรือคุณสามารถ ส่งภายในของวิธีการที่มีอยู่ นี่คือวิธีที่ฉันทำ:

ฉันเคยเข้าสู่สถานการณ์ที่ต้องรักษาความเข้ากันได้ย้อนหลัง วิธีการดั้งเดิมคาดว่าจะมีพารามิเตอร์สองตัว แต่วิธีใหม่มีเพียงพารามิเตอร์เดียวเท่านั้น การบรรทุกเกินพิกัดในวิธีที่ฉันคาดไว้ไม่ทำงานเนื่องจาก MVC ไม่พบจุดเริ่มต้นอีกต่อไป

เพื่อแก้ปัญหานั้นฉันทำสิ่งต่อไปนี้:

  1. เปลี่ยน 2 วิธีการกระทำที่มากเกินไปจากสาธารณะเป็นส่วนตัว
  2. สร้างวิธีสาธารณะใหม่หนึ่งวิธีซึ่งมีพารามิเตอร์สตริง "เพียงแค่" 2 ตัว ที่ทำหน้าที่เป็นดิสแพตเชอร์คือ:

    public ActionResult DoSomething(string param1, string param2)
    {
        if (string.IsNullOrEmpty(param2))
        {
            return DoSomething(ProductName: param1);
        }
        else
        {
            int oldId = int.Parse(param1);
            return DoSomething(OldParam: param1, OldId: oldId);
        }
    }
    
    
    private ActionResult DoSomething(string OldParam, int OldId)
    {
        // some code here
        return Json(result);
    }
    
    
    private ActionResult DoSomething(string ProductName)
    {
        // some code here
        return Json(result);
    }

แน่นอนว่านี่เป็นแฮ็คและควรได้รับการฟื้นฟูในภายหลัง แต่ในขณะนี้มันใช้งานได้สำหรับฉัน

คุณยังสามารถสร้างโปรแกรมเลือกจ่ายงานเช่น:

public ActionResult DoSomething(string action, string param1, string param2)
{
    switch (action)
    {
        case "update":
            return UpdateAction(param1, param2);
        case "remove":
            return DeleteAction(param1);
    }
}

คุณสามารถเห็นได้ว่า UpdateAction ต้องการพารามิเตอร์ 2 ตัวในขณะที่ DeleteAction ต้องการเพียงหนึ่งพารามิเตอร์


0

ขออภัยในความล่าช้า. ฉันมีปัญหาเดียวกันและฉันพบลิงค์ที่มีคำตอบที่ดีนั่นจะช่วยคนใหม่ได้

เครดิตทั้งหมดสำหรับเว็บไซต์ BinaryIntellect และผู้แต่ง

โดยทั่วไปมีสี่สถานการณ์: การใช้คำกริยา differents , การใช้เส้นทาง , การทำเครื่องหมายโอเวอร์โหลดด้วยแอตทริบิวต์ [NoAction]และเปลี่ยนชื่อแอ็ตทริบิวต์การกระทำด้วย [ActionName]

ดังนั้นขึ้นอยู่กับว่าข้อกำหนดของคุณและสถานการณ์ของคุณ

อย่างไรก็ตามไปตามลิงค์:

ลิงก์: http://www.binaryintellect.net/articles/8f9d9a8f-7abf-4df6-be8a-9895882ab562.aspx


-1

หากนี่เป็นความพยายามที่จะใช้หนึ่งการกระทำของ GET สำหรับหลาย ๆ มุมมองที่ POST ไปยังการกระทำหลายอย่างที่มีรูปแบบที่แตกต่างกันให้ลองเพิ่มการกระทำ GET สำหรับแต่ละการกระทำของ POST ที่เปลี่ยนเส้นทางไปยัง GET แรกเพื่อป้องกัน 404

ยิงยาว แต่สถานการณ์ทั่วไป

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