Die URL, die ich arbeiten zu lassen versuche, ist eine im Stil von: http://somedomain.com/api/people/staff.33311 (genau wie Websites wie LAST.FM alle Arten von zulassen B. " http://www.last.fm/artist/psy'aviah " ist eine gültige URL für LAST.FM.
Folgende Szenarien funktionieren: - http://somedomain.com/api/people/ - Gibt alle Personen zurück - http://somedomain.com/api/people/staff33311 - würde auch funktionieren, aber ich möchte nicht, dass die URL einen "Punkt" akzeptiert, wie im folgenden Beispiel - http://somedomain.com/api/people/ staff.33311 - aber das gibt mir eine
HTTP Error 404.0 - Not Found
The resource you are looking for has been removed, had its name changed, or is temporarily unavailable.
Ich habe folgende Dinge eingerichtet:
Die Steuerung "PeopleController"
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);
}
Die 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 }
);
}
Ich habe bereits versucht, alle Tipps dieses Blogposts zu befolgen http://www.hanselman.com/blog/ExperimentsInWackinessAllowingPercentsAnglebracketsAndOtherNaughtyThingsInTheASPNETIISRequestURL.aspx , aber es funktioniert immer noch nicht Wenn es keinen anderen, besseren und sichereren Weg gibt.
Wir haben unsere IDs intern so, also müssen wir eine Lösung finden, um den Punkt auf die eine oder andere Weise anzupassen, vorzugsweise im Stil von "." aber ich bin offen für alternative vorschläge für urls wenn nötig ...
Folgende Einstellung in Ihrem web.config
Datei sollte Ihr Problem beheben:
<configuration>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true" />
Fügen Sie der URL einen Schrägstrich hinzu, z. http://somedomain.com/api/people/staff.33311/
anstatt http://somedomain.com/api/people/staff.33311
.
Ich habe festgestellt, dass Hinzufügen das folgende Vorher der Standard ExtensionlessUrlHandler
das Problem für mich löst:
<add name="ExtensionlessUrlHandler-Integrated-4.0-ForApi"
path="api/*"
verb="*"
type="System.Web.Handlers.TransferRequestHandler"
preCondition="integratedMode,runtimeVersionv4.0" />
Ich denke nicht, dass der Name wirklich so wichtig ist, außer dass es wahrscheinlich hilft, wenn Ihr IDE (Visual Studio in meinem Fall) Ihre Site-Konfiguration verwaltet.
Ich weiß nicht, was ich wirklich tue, aber nachdem ich ein bisschen mit der vorherigen Antwort gespielt hatte, kam ich auf eine andere, vielleicht passendere Lösung:
<system.webServer>
<modules>
<remove name="UrlRoutingModule-4.0" />
<add name="UrlRoutingModule-4.0" type="System.Web.Routing.UrlRoutingModule" />
</modules>
</system.webServer>
Ich stellte fest, dass ich mehr tun musste, als nur das runAllManagedModulesForAllRequests
-Attribut auf true
zu setzen. Ich musste auch sicherstellen, dass der erweiterungslose URL-Handler so konfiguriert war, dass alle Pfade angezeigt wurden. Darüber hinaus können Sie eine weitere Bonuskonfigurationseinstellung hinzufügen, die in einigen Fällen hilfreich ist. Hier ist meine funktionierende 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>
Beachten Sie insbesondere, dass für ExtensionlessUrlHandler-Integrated-4.0
Das Attribut path
auf *
Festgelegt ist, im Gegensatz zu *.
(Zum Beispiel).
Ich steckte in dieser Situation fest, fügte aber /
am Ende der URL sah für mich nicht sauber aus.
füge also einfach das unten stehende web.confighandlers
Tag hinzu und du kannst loslegen.
<add name="Nancy" path="api" verb="*" type="Nancy.Hosting.Aspnet.NancyHttpRequestHandler" allowPathInfo="true" />
Ich stellte fest, dass beide Methoden für mich funktionieren: Setzen Sie entweder runAllManagedModulesForAllRequests auf true oder fügen Sie ExtentionlessUrlHandler wie folgt hinzu. Schließlich entscheide ich mich, extensionUrLHandler hinzuzufügen, da runAllManagedModulesForAllRequests die Leistung der Site beeinträchtigen.
<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>
Ich hatte genau das gleiche Problem und die Umstände, unter denen ich nicht mit den Einstellungen für IIS und die Website-Konfiguration spielen sollte. Daher musste ich Änderungen auf Code-Ebene vornehmen, um das Problem zu lösen nur.
Der einfache Punkt ist, dass der häufigste Fall, in dem Sie Punktzeichen in der URL haben, darin besteht, dass Sie eine Eingabe vom Benutzer erhalten und diese als Abfragezeichenfolge oder URL-Fragment übergeben, um ein Argument an die Parameter in der Aktionsmethode zu übergeben Ihres Controllers.
public class GetuserdetailsbyuseridController : ApiController
{
string getuserdetailsbyuserid(string userId)
{
//some code to get user details
}
}
Schauen Sie sich die folgende URL an, unter der der Benutzer seine Benutzer-ID eingibt, um seine persönlichen Daten abzurufen:
http://mywebsite:8080/getuserdetailsbyuserid/foo.bar
Da Sie einfach einige Daten vom Server abrufen müssen, verwenden wir http GET
verb. Bei Verwendung von GET
-Aufrufen können Eingabeparameter nur in den URL-Fragmenten übergeben werden.
Um mein Problem zu lösen, habe ich das http-Verb meiner Aktion in POST
geändert. Http POST
verb hat die Möglichkeit, Benutzer- oder Nichtbenutzereingaben auch in body zu übergeben. Also habe ich JSON-Daten erstellt und diese an den Text der http POST
-Anforderung übergeben:
{
"userid" : "foo.bar"
}
Ändern Sie Ihre Methodendefinition wie folgt:
public class GetuserdetailsbyuseridController : ApiController
{
[Post]
string getuserdetailsbyuserid([FromBody] string userId)
{
//some code to get user details
}
}
Hinweis : Weitere Informationen zur Verwendung von GET
verb und zur Verwendung von POST
verb hier =.