Nokta karakteri "." MVC Web API 2'de api / people / STAFF.45287 gibi talepler için


106

Çalışmasına izin vermeye çalıştığım URL şu tarzda bir URL: http://somedomain.com/api/people/staff.33311 (tıpkı LAST.FM'nin RESTFul ve WebPage url'lerinde her tür işarete izin verdiği siteler gibi , örneğin " http://www.last.fm/artist/psy'aviah ", LAST.FM için geçerli bir url'dir).

İşe yarayan senaryolar şunlardır: - http://somedomain.com/api/people/ - tüm insanları döndüren - http://somedomain.com/api/people/staff33311 - da işe yarayacak, ancak bu benim gibi değil ' m sonra, url'nin aşağıdaki örnekte olduğu gibi bir "nokta" kabul etmesini istiyorum - http://somedomain.com/api/people/staff.33311 - ama bu bana bir

HTTP Error 404.0 - Not Found
The resource you are looking for has been removed, had its name changed, or is temporarily unavailable.

Aşağıdaki şeyleri kurdum:

  1. "PeopleController" denetleyicisi

    public IEnumerable<Person> GetAllPeople()
    {
        return _people;
    }
    
    public IHttpActionResult GetPerson(string id)
    {
        var person = _people.FirstOrDefault(p => p.Id.ToLower().Equals(id.ToLower()));
        if (person == null)
            return NotFound();
    
        return Ok(person);
    }    
  2. WebApiConfig.cs

    public static void Register(HttpConfiguration config)
    {
        // Web API configuration and services
    
        // Web API routes
        config.MapHttpAttributeRoutes();
    
        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );
    }

Bu blog gönderisinin tüm ipuçlarını izlemeyi zaten denedim http://www.hanselman.com/blog/ExperimentsInWackinessAllowingPercentsAnglebracketsAndOtherNaughtyThingsInTheASPNETIISRequestURL.aspx ama yine de işe yaramıyor .. Ayrıca oldukça sıkıcı olduğunu düşünüyorum ve başka bir şey olup olmadığını merak ediyorum. daha iyi ve daha güvenli bir yol.

Kimliğimizin dahili olarak böyle olması nedeniyle, noktayı şu ya da bu şekilde, tercihen "" tarzında yerleştirmek için bir çözüm bulmamız gerekecek. ancak gerekirse url'ler için alternatif önerilere açığım ...


10
Bir yanıt değil, ancak somedomain.com/api/people/staff.33311 için neden 404 aldığınıza gelince - varsayılan olarak, IIS bu URL'ye bakar ve. bir dosya uzantısı olarak ve MVC API'nizi atlayarak statik dosya işleyicisini çağırır. Kabul ettiğiniz yanıt (tüm istekler için tüm yönetilen modülleri çalıştırma) işe yarıyor çünkü IIS'ye yapılan her isteği ASP.NET işlem hattından
Henry C

Yakından ilgili gönderi burada .
RBT

Yanıtlar:


104

web.configDosyanızdaki aşağıdaki ayar sorununuzu çözmelidir:

<configuration>
    <system.webServer>
        <modules runAllManagedModulesForAllRequests="true" />

4
Hile yaptı. Yine de, bu seçeneği ayarladığınızda herhangi bir güvenlik açığı var mı? Neden bu standart davranış değil?
Yves Schelpe

2
Tamam, herkesin ilgisini
çekmek için

2
Evet, işe yaradı, diğerlerini otobüsle, bu işlevselliğin çalışması için hangi belirli modülün gerekli olduğunu bilmek isterim?
Greg Z.17

3
Bunu denediğimde, sadece yolun sonuna bir "/" koyarsam işe yarar. Bunun neden olduğu konusunda herhangi bir öneriniz var mı? Bir yan not olarak, tüm modülleri çalıştırmak yerine özel olarak 'UrlRoutingModule' ekleyen aşağıdaki cevap, benim için de işe yaradı, ancak yine de sonunda çalışmak için bir '/' gerektirmesi sorunuyla birlikte.
Nikolaj Dam Larsen,

10
stackoverflow.com/a/12151501/167018 , runAllManagedModulesForAllRequests'i etkinleştirmenin performans üzerindeki etkisi konusunda endişeleriniz varsa (ve haklı olarak öyle) bakmaya değer.
Henry C

140

URL'nin sonuna örneğin http://somedomain.com/api/people/staff.33311/yerine eğik çizgi koyun http://somedomain.com/api/people/staff.33311.


3
@AgustinMeriles Cevabım gerçek bir cevaptan çok geçici bir çözüm olarak düşünülebilir, soruyu yorumlamanıza bağlıdır.
Danny Varod

5
Bu, nokta / people / member içindeki gibi URL bölümünün sonunda olduğunda işe yaramaz.
eYe

2
Hayır, ya sonunda bir kesme işareti istemiyorsam ?! O gerektiğini değil gerekli.
Josh M.

1
@JoshM. Bu geçici bir çözüm, ASP.NET yazmadım. Ayrıca, eğik çizgi isteği etkilemez. Bununla birlikte, niyetlerinizi google.com/my query goes here/vs. gibi daha net hale getirmenize yardımcı olur.google.com/subDomain my query goes here .
Danny Varod

1
Evet, web.config'i değiştirmek zorunda olmamanız gereken en iyisi budur.
Timothy Gonzalez

35

Standarttan önce aşağıdakileri eklemenin sorunu benim için çözdüğünü gördüm :ExtensionlessUrlHandler

<add name="ExtensionlessUrlHandler-Integrated-4.0-ForApi"
     path="api/*"
     verb="*"
     type="System.Web.Handlers.TransferRequestHandler"
     preCondition="integratedMode,runtimeVersionv4.0" />

IDE'niz (benim durumumda Visual Studio) site yapılandırmanızı yönetiyorsa, adın aslında o kadar önemli olduğunu sanmıyorum.

H / T için https://stackoverflow.com/a/15802305/264628


Standart çizgiden 'sonra' ekledim ve aynı zamanda iyi çalıştı.
Jalal El-Shaer

Kabul edilen cevap bu olmalıdır. Uri sonunda / gerektirmez
daudihus

2
ÖNCE için teşekkürler, çünkü daha sonra işe yaramadı!
Mese

Modüllerin bildirim sırasına göre çalıştığına inanıyorum, bu yüzden her zaman daha spesifik (veya daha önemli) olanları daha genel olanların önüne koyun.
BrianS

24

Gerçekte ne yaptığımı bilmiyorum ama önceki cevapla biraz oynadıktan sonra, belki daha uygun başka bir çözüm buldum:

<system.webServer>
<modules>
    <remove name="UrlRoutingModule-4.0" />
    <add name="UrlRoutingModule-4.0" type="System.Web.Routing.UrlRoutingModule" />
</modules>
</system.webServer>

Teşekkürler, ne yaptığını da bilmiyorum ama diğer çözümden daha iyi görünüyor.
Thomas

1
url yönlendirme modülünü (isteğin bir uzantı içerdiğini ve daha sonra bunu bir dosya olarak işlemeye çalıştığını) modül listesinin sonuna taşıdığı görülüyor; . IMHO, bu, SO'da
James Manning

1
Bu, listenin sonuna yer değiştirme değil, bu modülün yalnızca yönetilen işleyiciler için çalıştırılması şeklindeki varsayılan ön koşulun kaldırılmasıdır. Varsayılan yapılandırma şu biçimi kullanır:<add name="UrlRoutingModule-4.0" type="System.Web.Routing.UrlRoutingModule" preCondition="managedHandler" />
theta-fish

Teşekkürler - bu davranışı açıklar.
Greg Z.

8

runAllManagedModulesForAllRequestsÖzniteliği olarak ayarlamaktan daha fazlasını yapmam gerektiğini fark ettim true. Ayrıca, uzantısız URL işleyicisinin tüm yollara bakacak şekilde yapılandırıldığından emin olmalıydım. Ek olarak, ekleyebileceğiniz ve bazı durumlarda yardımcı olacak bir bonus yapılandırma ayarı daha vardır. İşte benim çalışan Web.config:

<system.web>
    <httpRuntime relaxedUrlToFileSystemMapping="true" />
</system.web>
<system.webServer>
    <modules runAllManagedModulesForAllRequests="true" />
    <handlers>
        <remove name="WebDAV" />
        <remove name="OPTIONSVerbHandler" />
        <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
        <add name="ExtensionlessUrlHandler-Integrated-4.0"  path="*" verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
    </handlers>
</system.webServer>

Not, özel olarak ise, bu ExtensionlessUrlHandler-Integrated-4.0da vardır pathöznitelik grubu *karşıt olarak *.(örneğin).


Sadece tarafından ısırıldım path="*.". Sadece merak ediyorum, insanların bunu ayarlamasının nedeni path="*."nedir?
JustinP8

Aslında, olarak değiştirdim path="*"ve bir sorunla karşılaştım çünkü WebAPI'mızla yan yana bir dokümantasyon sitesi barındırıyoruz ve bu sitede .jpg, .png ve uzantılara sahip diğer dosyalarla ilgili sorunlar vardı.
JustinP8

@ JustinP8 de ayarladınız <modules runAllManagedModulesForAllRequests="true" />mı? Bu, .NET'in bu statik dosyaları işlemesini sağlamalıdır.
Josh M.

1
Evet. Bunu yaparken yaralandım. Bundan hoşlanmıyorum çünkü artık tüm statik dosyalar .NET işlem hattından geçiyor. Neyse ki, bu bir webAPI hizmeti olduğundan, yalnızca API belgeleri / yardımcı site için Swagger ve Swashbuckle öğeleri etkilenir.
JustinP8

Bunun tüm statik dosya isteklerini bozduğunu buldum. 500 hatası. runAllManaged ... öğesini true olarak ayarladım.
Sam

2

Bu durumda sıkışıp kaldım ancak / URL'nin sonuna eklemek benim için temiz görünmedi.

bu yüzden web.config handlers etiketine aşağıyı ekleyin ve gitmeniz iyi olur.

<add name="Nancy" path="api" verb="*" type="Nancy.Hosting.Aspnet.NancyHttpRequestHandler" allowPathInfo="true" />

Nancy'nin ne olduğunu ve projeye dahil edilecek bir kütüphane olup olmadığını açıklayabilir misiniz? Teşekkürler!
mavimsi

1

Her iki yolun da benim için işe yaradığını buldum: ya runAllManagedModulesForAllRequests'i true olarak ayarlamak veya ExtentionlessUrlHandler'ı aşağıdaki gibi eklemek. Son olarak, runAllManagedModulesForAllRequests'in siteye performans etkisi olduğu için extensionUrLHandler eklemeyi seçiyorum.

<handlers>
  <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
  <remove name="OPTIONSVerbHandler" />
  <remove name="TRACEVerbHandler" />
  <remove name="WebDAV" />
  <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*" verb="*" 
       type="System.Web.Handlers.TransferRequestHandler" 
       preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>

1

Bunu Web.config dosyasında kullanırdım:

<add name="ManagedSpecialNames" path="api/people/*" verb="GET" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />

standart "ExtensionlessUrlHandler" dan önce.

Örneğin benim durumumda buraya koyuyorum:

<handlers>
  <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
  <remove name="OPTIONSVerbHandler" />
  <remove name="TRACEVerbHandler" />
  <add name="ManagedFiles" path="api/people/*" verb="GET" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
  <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>

Bu nedenle, bu tür bir modelin URL'lerini, uygulama dizin ağacındaki dosyalar olarak standart yönetim yerine, sizin tarafınızdan yönetilmeye zorlarsınız.


0

Aynı sorunla ve IIS ve web sitesi yapılandırmasıyla ilgili ayarlarla oynamamam gereken koşullarla karşılaştım. Bu yüzden sadece kod seviyesinde değişiklikler yaparak onu çalıştırmalıydım.

Basit nokta, URL'de nokta karakterine sahip olacağınız en yaygın durum, kullanıcıdan bir miktar girdi aldığınızda ve bunu eylem yöntemindeki parametrelere bir argüman iletmek için bir sorgu dizesi veya url parçası olarak ilettiğiniz zamandır. denetleyicinizin.

public class GetuserdetailsbyuseridController : ApiController
{
     string getuserdetailsbyuserid(string userId)
     {
        //some code to get user details
     }
}

Kullanıcının kişisel bilgilerini almak için kullanıcı kimliğini girdiği aşağıdaki URL'ye bir göz atın:

http://mywebsite:8080/getuserdetailsbyuserid/foo.bar

Sunucudan bazı verileri basitçe almanız gerektiğinden, http GETfiilini kullanıyoruz. GETÇağrılar kullanılırken herhangi bir girdi parametresi yalnızca URL parçalarında geçirilebilir.

Bu yüzden problemimi çözmek için eylemimin http fiilini olarak değiştirdim POST. Http POSTfiili, herhangi bir kullanıcı veya kullanıcı olmayan girdiyi gövdede de geçirme özelliğine sahiptir. Bu yüzden bir JSON verisi oluşturdum ve bunu http POSTisteğinin gövdesine aktardım :

{
  "userid" : "foo.bar"
}

Yöntem tanımınızı aşağıdaki gibi değiştirin:

public class GetuserdetailsbyuseridController : ApiController
{
     [Post]
     string getuserdetailsbyuserid([FromBody] string userId)
     {
        //some code to get user details
     }
}

Not : GETFiilin ne zaman ve ne zaman kullanılacağıyla ilgili daha fazla POSTbilgiyi burada bulabilirsiniz .


Bir REST API oluşturuyorsanız uygun bir çözüm değildir.
Mustafa Öztürk
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.