asp.net - Web API Routing-api /{controller}/{action}/{id}"dysfunctions" api /{controller}/{id}




asp.net-web-api (3)

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

لذلك يجب عليك:

  1. ضع القواعد المحددة الخاصة بك قبل القواعد العامة (مثل الافتراضي) ، مما يعني استخدام RouteTable.Routes.MapHttpRoute لتعيين "WithActionApi" أولاً ، ثم "DefaultApi".

  2. إزالة defaults: new { id = System.Web.Http.RouteParameter.Optional } معلمة defaults: new { id = System.Web.Http.RouteParameter.Optional } الجديدة لقاعدة "WithActionApi" نظرًا لأن معرف الهوية اختياري ، لن يتم الانتقال إلى عنوان url مثل "/ api / {part1} / {part2}" أبدًا. DefaultApi ".

  3. قم بإضافة إجراء مسمى إلى "DefaultApi" لإخبار محرك المسار بإدخال الإجراء. وإلا إذا كان لديك أكثر من إجراء واحد في وحدة التحكم ، فلن يعرف المحرك أيًا منهما يستخدم ويرمي "تم العثور على إجراءات متعددة تتطابق مع الطلب: ...". ثم لجعله يطابق طريقة Get ، استخدم ActionNameAttribute .

لذلك يجب أن يعجبك هذا المسار:

// Map this rule first
RouteTable.Routes.MapRoute(
     "WithActionApi",
     "api/{controller}/{action}/{id}"
 );

RouteTable.Routes.MapRoute(
    "DefaultApi",
    "api/{controller}/{id}",
    new { action="DefaultAction", id = System.Web.Http.RouteParameter.Optional }
);

وجهاز التحكم الخاص بك:

[ActionName("DefaultAction")] //Map Action and you can name your method with any text
public string Get(int id)
{
    return "object of id id";
}        

[HttpGet]
public IEnumerable<string> ByCategoryId(int id)
{
    return new string[] { "byCategory1", "byCategory2" };
}

لدي المسار الافتراضي في Global.asax:

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

أردت أن أتمكن من استهداف وظيفة محددة ، لذلك قمت بإنشاء مسار آخر:

RouteTable.Routes.MapHttpRoute(
         name: "WithActionApi",
         routeTemplate: "api/{controller}/{action}/{id}",
         defaults: new { id = System.Web.Http.RouteParameter.Optional }
         );

لذا ، في وحدة التحكم الخاصة بي ، لدي:

    public string Get(int id)
    {
        return "object of id id";
    }        

    [HttpGet]
    public IEnumerable<string> ByCategoryId(int id)
    {
        return new string[] { "byCategory1", "byCategory2" };
    }

الاتصال .../api/records/bycategoryid/5 سوف يعطيني ما أريد. ومع ذلك ، الاتصال .../api/records/1 سوف يعطيني الخطأ

تم العثور على إجراءات متعددة تتطابق مع الطلب: ...

أفهم سبب ذلك - تحدد المسارات فقط ما هي عناوين URL الصالحة ، ولكن عندما يتعلق الأمر بمطابقة الوظائف ، ByCategoryId(int id) Get(int id) و ByCategoryId(int id) مع api/{controller}/{id} ، وهو ما يخلط إطار العمل.

ما الذي يتعين عليّ فعله لإعادة مسار واجهة برمجة التطبيقات الافتراضي مرة أخرى ، والحفاظ على المسار باستخدام {action} ؟ فكرت في إنشاء وحدة تحكم مختلفة باسم RecordByCategoryIdController مع مسار واجهة برمجة التطبيقات الافتراضي ، الذي .../api/recordbycategoryid/5 . ومع ذلك ، أجد أن هذا هو الحل "القذرة" (وبالتالي غير مرضية). لقد بحثت عن إجابات حول هذا الأمر ولم يقدم أي برنامج تعليمي حول استخدام مسار مع {action} حتى هذه المشكلة.


يمكنك حل مشكلتك بمساعدة توجيه السمة

مراقب

[Route("api/category/{categoryId}")]
public IEnumerable<Order> GetCategoryId(int categoryId) { ... }

URI في jquery

api/category/1

تكوين الطريق

using System.Web.Http;

namespace WebApplication
{
    public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            // Web API routes
            config.MapHttpAttributeRoutes();

            // Other Web API configuration not shown.
        }
    }
}

ويعمل التوجيه الافتراضي الخاص بك كإجراء افتراضي يعتمد على اصطلاح

مراقب

public string Get(int id)
    {
        return "object of id id";
    }   

URI في مسج

/api/records/1 

تكوين الطريق

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        // Attribute routing.
        config.MapHttpAttributeRoutes();

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

مراجعة المقالة لمزيد من المعلومات توجيه السمة والتوجيه القائم على onvention هنا this


تريد شيئًا مثل:

<appSettings>
  <add key="developmentModeUserId" xdt:Transform="Remove" xdt:Locator="Match(key)"/>
  <add key="developmentMode" value="false" xdt:Transform="SetAttributes"
          xdt:Locator="Match(key)"/>
</appSettings>

راجع http://msdn.microsoft.com/en-us/library/dd465326(VS.100).aspx للحصول على مزيد من المعلومات.





asp.net routing controller asp.net-web-api action