我很好奇如果你可以载控制方法ASP.NET 视.每当我试着,我得到的错误之下。两种方法的接受不同的参数。这是什么,不能做什么?

目前的请求采取行动'MyMethod'在控制器类型'MyController'是模棱两可之间,以下行动方法:

有帮助吗?

解决方案

你可以使用的属性如果你想要你的代码做过载。

[ActionName("MyOverloadedName")]

但是,你必须使用一个不同的行动,名字相同http方法(正如其他人所说的那样).所以这只是语义。你想有名字在你的代码或是你的属性?

菲尔有一篇文章关于: http://haacked.com/archive/2008/08/29/how-a-method-becomes-an-action.aspx

其他提示

是。我已经能够通过为每个控制器方法HttpGet / HttpPost(或等效AcceptVerbs属性)设定为不同的东西,即,HttpGetHttpPost做到这一点,但不能同时使用。这样,它可以告诉基于对请求使用哪种方法的类型。

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

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

一个建议我是,像这样的情况下,将有一个私人的实现,您的两个公益行动的方法依赖于以避免重复的代码。

下面是别的东西,你可以做......你想要的是能够有一个参数,而不是一个方法。

为什么不试试这个...

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

这很适合我......在这一个方法,你可以实际测试,看看你是否有传入的参数。


更新,删除上串无效可为空的语法和使用默认参数值。

没有,没有,没有。去尝试的控制下面的代码在哪里我们有"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"行动你会得到错误,如下图所示.

enter image description here

多态性的一部分C#编程,同时HTTP是一个协议。HTTP不了解多态性。HTTP工作在概念上的或网址和网址可只有唯一的名称。所以HTTP没有实现多态性。

为了解决同样,我们需要使用"的"属性。

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"的行动将被援用并用的网址结构"客户/LoadCustomerByName"的"LoadCustomer(string str)"将被援引。

enter image description here

enter image description here

上述答案我从这个演示文--> 视作超载

要克服这个问题,你可以写检查ActionMethodSelectorAttribute每个动作,并比较其张贴表格值,然后拒绝的量,形式值不匹配任何方法的MethodInfo(不含按钮名称,当然)。

下面是一个例子: - HTTP://博客。 abodit.com/2010/02/asp-net-mvc-ambiguous-match/

但是,这不是一个好主意。

据我知道使用不同的HTTP方法时,你可以只具有相同的方法。

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

}

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

}

我已经实现了这样的帮助 属性的路由 在MVC5.当然我是新来的视来自一个十年的网页开发利用web表单,但以下已为我工作。不接受,回答这个允许所载的行动呈现同样的观点的文件。

第一个启用路由属性在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)
{
    //.....
}

希望这可以帮助而不是领导人下了错误的道路。:-)

您可以使用单个ActionResult同时处理PostGet

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

有用的,如果你的GetPost方法具有匹配的签名。

我刚刚遇到这个问题,即使它很老了,它仍然非常相关的。具有讽刺意味的是,一个正确的评论,在此主题发表过一个自认为是初学者在视,当时他写的员额。即使是ASP.NET 文件不完全正确的。我有一个大项目,我成功过载行动方法。

如果一个人理解的路由,超越了简单{控制器}/{行动}/{id}默认的路线图,它可能是显而易见的是,控制的行动可以映射使用的任何独特的模式。有人在这里谈到了多态性的,说:"HTTP不了解多态性",但路由没有任何与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
    }
}

这些行动将照顾网址喜欢 /cars/usa/new-york/cars/usa/texas/dallas, ,这将地图的第一和第二索引的行动。

检查这个例子控制器,这是显而易见,它远远超出了默认的路线图上所述。默认有效的,如果你的网址结构的完全匹配你的代码命名约定,但这并不总是这种情况。代码应该是描述性的领域,但网址常常需要更进一步,因为它们的内容应该根据其他标准,例如SEO的要求。

受益于默认的路由选择模式是,它自动创造了独特的路线。这是强制执行通过的编译器,因为网址将匹配的唯一控制器类型和成员。滚你自己的路线模式将需要认真思考,以确保独特性和他们的工作。

重要的注意 一个缺点是,使用路由生成的网址载的行动不起作用时,基于行动的名称,例如,当使用UrlHelper.行动。但它的工作,如果一个使用名为路线,例如,UrlHelper.RouteUrl.和使用的命名的路线,根据备受尊敬的来源、路要走,无论如何(http://haacked.com/archive/2010/11/21/named-routes-to-the-rescue.aspx/).

祝你好运!

可以使用[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");
    }
}

我所需的过载:

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
    }
}

这不是一个完美的解决方案,特别是如果你有很多的争论,但它很适合我。

我在我的应用面临着同样的问题了。没有任何Modifiyig方法的信息,我已经提供了[ActionName(“SomeMeaningfulName”)]就头。问题解决

[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);

        }

创建基础的方法虚拟

public virtual ActionResult Index()

创建重写的方法作为覆盖

public override ActionResult Index()

编辑:这显然仅适用于超控方法是在其中出现不一直是OP意图的派生类

我喜欢这个答案张贴在另一个线程

如果从另一个控制器继承和要重写从基部控制器的acction这主要用于

ASP.NET MVC - 覆盖具有不同参数的动作

每个控制器方法只允许有一个公共签名。如果您尝试重载它,它会编译,但您会遇到所经历的运行时错误。

如果您不愿意使用不同的动词(例如 [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);
    }
    

当然,这是一个 hack,应该稍后重构。但就目前而言,它对我有用。

您还可以创建一个调度程序,例如:

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 只需要 1 个。

如果这是使用该职位与不同型号的几个操作中的多个视图中的一个GET动作,然后尝试添加对重定向到第一个GET,以防止刷新404均POST动作的GET动作的尝试。

长镜头,但常见的情况。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top