هل يمكنك زيادة تحميل أساليب التحكم في ASP.NET MVC؟

StackOverflow https://stackoverflow.com/questions/436866

  •  22-07-2019
  •  | 
  •  

سؤال

أشعر بالفضول لمعرفة ما إذا كان بإمكانك زيادة التحميل على أساليب التحكم في ASP.NET MVC.كلما حاولت، أحصل على الخطأ أدناه.تقبل الطريقتان وسيطات مختلفة.هل هذا شيء لا يمكن القيام به؟

الطلب الحالي للإجراء "MyMethod" على نوع وحدة التحكم "MyController" غامض بين طرق الإجراء التالية:

هل كانت مفيدة؟

المحلول

ويمكنك استخدام السمة إذا كنت تريد التعليمات البرمجية للقيام الزائد.

[ActionName("MyOverloadedName")]

ولكن، سيكون لديك لاستخدام اسم عمل مختلفة لنفس طريقة HTTP (كما قال آخرون). لذلك فمن دلالات فقط عند تلك النقطة. هل لديك بدلا من اسم في التعليمات البرمجية أو السمة الخاصة بك؟

وفيل ديه مقالا حول هذا: <لأ href = "http://haacked.com/archive/2008/08/29/how-a-method-becomes-an-action.aspx" يختلط = "noreferrer "> http://haacked.com/archive/2008/08/29/how-a-method-becomes-an-action.aspx

نصائح أخرى

نعم. لقد كنت قادرا على القيام بذلك عن طريق وضع HttpGet / HttpPost (أو سمة AcceptVerbs ما يعادلها) لكل أسلوب تحكم إلى شيء واضح، أي HttpGet أو HttpPost، ولكن ليس على حد سواء. وبهذه الطريقة يمكن أن اقول بناء على نوع الطلب الطريقة التي يجب استخدامها.

[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" العمل ستحصل على خطأ كما هو مبين في الشكل أدناه.

وتعدد الأشكال هو جزء من البرمجة 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 (سلسلة شارع)" سيتم استدعاؤه.

والجواب أعلاه لقد اتخذت من هذه المادة codeproject -> <وأ href = "http://www.codeproject.com/Articles/846403/Can-we-overload-MVC-controller-action-methods-MVC "يختلط =" noreferrer "> MVC العمل الزائد

لتجاوز هذه المشكلة التي <م> يمكن كتابة 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)
{

}

ولقد تحقق ذلك بمساعدة <لأ href = "http://blogs.msdn.com/b/webdev/archive/2013/10/17/attribute-routing-in-asp-net-mvc- 5.aspx "يختلط =" noreferrer "> السمة التوجيه في 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)
{
    //.....
}

وآمل أن يساعد هذا ولا يؤدي شخص ما في الطريق الخطأ. : -)

هل يمكن استخدام ActionResult واحدة للتعامل مع كل Post وGet:

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

ومفيدة إذا كانت لديك Get وPost طرق التوقيعات مطابقة.

لقد صادفني هذا السؤال للتو، وعلى الرغم من أنه قديم جدًا الآن، إلا أنه لا يزال وثيق الصلة بالموضوع.ومن المفارقات أن التعليق الصحيح الوحيد في هذا الموضوع تم نشره بواسطة مبتدئ اعترف بذاته في MVC عندما كتب المنشور.حتى مستندات ASP.NET ليست صحيحة تمامًا.لدي مشروع كبير وقد نجحت في تحميل أساليب العمل بشكل زائد.

إذا فهم المرء التوجيه، بما يتجاوز نمط المسار الافتراضي {controller}/{action}/{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
    }
}

ستهتم هذه الإجراءات بعناوين 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/).

حظ سعيد!

ويمكنك استخدام [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. تم إنشاء طريقة عامة جديدة تحتوي على معلمتين من السلسلة "فقط".وكان ذلك الشخص بمثابة المرسل، أي:

    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 يحتاج إلى معلمتين، بينما يحتاج RemoveAction إلى معلمة واحدة فقط.

وإذا كان هذا هو محاولة لاستخدام العمل GET واحد لعدة جهات النظر هذا المنصب لعدة إجراءات مع نماذج مختلفة، ثم حاول إضافة إجراء GET لكل عمل ما بعد أن الموجهات إلى GET الأول لمنع 404 على التحديث.

واطلاق النار طويل ولكن السيناريو الشائع.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top