私が動作させようとしているURLは、次のスタイルのURLです。 http://somedomain.com/api/people/staff.33311 (LAST.FMがあらゆる種類のサイトを許可するようにRESTFulおよびWebPageのURLにサインインします。たとえば、「 http://www.last.fm/artist/psy'aviah はLAST.FMの有効なURLです)。
動作するシナリオは次のとおりです。- http://somedomain.com/api/people/ -すべてのユーザーを返します- http://somedomain.com/api/people/staff33311 -同様に機能しますが、次の例のように、URLに「ドット」を受け入れさせたいとは思っていません- http://somedomain.com/api/people/ staff.33311 -しかし、これは私に与えます
HTTP Error 404.0 - Not Found
The resource you are looking for has been removed, had its name changed, or is temporarily unavailable.
私は次のものを設定しました:
コントローラー「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);
}
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 }
);
}
私はすでにこのブログ投稿のすべてのヒントに従うことを試みました http://www.hanselman.com/blog/ExperimentsInWackinessAllowingPercentsAnglebracketsAndOtherNaughtyThingsInTheASPNETIISRequestURL.aspx それはまだ機能しないと思います。別の、より良い、より安全な方法がない場合。
内部的にはこのようなIDを持っているので、ドットを何らかの方法で、できれば "。"のスタイルでフィットさせる解決策を見つける必要があります。しかし、必要に応じてURLの代替提案を受け入れています...
web.config
ファイルの次の設定で問題を修正できます。
<configuration>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true" />
URLの末尾にスラッシュを付けます。 http://somedomain.com/api/people/staff.33311/
の代わりにhttp://somedomain.com/api/people/staff.33311
。
追加次のbefore標準ExtensionlessUrlHandler
が問題を解決することがわかりました。
<add name="ExtensionlessUrlHandler-Integrated-4.0-ForApi"
path="api/*"
verb="*"
type="System.Web.Handlers.TransferRequestHandler"
preCondition="integratedMode,runtimeVersionv4.0" />
名前は、IDE(私の場合はVisual Studio)がサイト構成を管理している場合におそらく役立つことを除いて、実際にそれほど重要ではないと思います。
私は本当に何をしているのかわかりませんが、前の回答で少し遊んだ後、別の、おそらくより適切な解決策を思いつきました:
<system.webServer>
<modules>
<remove name="UrlRoutingModule-4.0" />
<add name="UrlRoutingModule-4.0" type="System.Web.Routing.UrlRoutingModule" />
</modules>
</system.webServer>
runAllManagedModulesForAllRequests
属性をtrue
に設定する以上のことを行う必要があることがわかりました。また、すべてのパスを参照するように拡張機能なしのURLハンドラーを構成する必要がありました。さらに、追加できるボーナス構成設定がもう1つあり、これは場合によっては役立ちます。これが私の作業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>
特に、ExtensionlessUrlHandler-Integrated-4.0
のpath
属性は、*
(たとえば)ではなく*.
に設定されていることに注意してください。
私はこの状況で立ち往生しましたが、URLの最後に/
を追加してもきれいに見えませんでした。
web.confighandlers
タグに以下を追加するだけで準備完了です。
<add name="Nancy" path="api" verb="*" type="Nancy.Hosting.Aspnet.NancyHttpRequestHandler" allowPathInfo="true" />
私は両方の方法がうまくいくことを発見しました:runAllManagedModulesForAllRequestsをtrueに設定するか、次のようにExtentionlessUrlHandlerを追加します。最後に、runAllManagedModulesForAllRequestsはサイトのパフォーマンスに影響するため、extensionUrLHandlerを追加することを選択します。
<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>
私はIISおよびウェブサイトの設定に関連する設定でプレイすることになっていない非常に同じ問題と状況に直面しました。そのため、コードレベルでのみ変更を加えて機能させる必要がありました。
簡単な点は、URLにドット文字が含まれることになる最も一般的なケースは、ユーザーから入力を取得し、それをクエリ文字列またはURLフラグメントとして渡して、アクションメソッドのパラメーターに引数を渡すことです。あなたのコントローラーの。
public class GetuserdetailsbyuseridController : ApiController
{
string getuserdetailsbyuserid(string userId)
{
//some code to get user details
}
}
ユーザーが個人情報を取得するためにユーザーIDを入力するURLを以下に示します。
http://mywebsite:8080/getuserdetailsbyuserid/foo.bar
サーバーからデータを取得するだけなので、http GET
動詞を使用します。 GET
呼び出しを使用している間、入力パラメーターはURLフラグメントでのみ渡すことができます。
そこで、問題を解決するために、アクションのhttp動詞をPOST
に変更しました。 Http POST
動詞には、ユーザーまたはユーザー以外の入力を本文で渡す機能もあります。そこで、JSONデータを作成し、http POST
リクエストの本文に渡しました。
{
"userid" : "foo.bar"
}
メソッド定義を次のように変更します。
public class GetuserdetailsbyuseridController : ApiController
{
[Post]
string getuserdetailsbyuserid([FromBody] string userId)
{
//some code to get user details
}
}
注:GET
verbを使用する場合とPOST
verbを使用する場合の詳細 here 。