1

私は MVC には比較的慣れていませんが、それを使用して標準のユーザー主導の CRUD サイトを構築することに成功したので、いくつかの基本を理解しています。私は、MVC 4 で構築された REST-ful api アプリになりたいことに取り組み始めました。この新しいアプリでコントローラーに解決する単純な要求を取得するという新人の問題があると確信しています。

POST 操作をサポートすることを目的とした単純なテスト リソースで、202 ではなく 404 が表示されます。このサイトでルートの問題の解決策を検索し、ハードワイヤードおよびパラメーター化されたルートとデフォルト値のさまざまな組み合わせを試しましたが、簡単に修正できると思われるものはまだ見つかりませんでした.

アップデート

また、MapRoute() の代わりに MapHttpRoute() を使用するように、ルート構成の設定を変更してみました (以下の Route Config #1 と #2 を参照)。これは何の効果もありませんでした。

これらはどちらも、2 つの異なるポートでリッスンする 2 つの異なるサイトとして構成された、1 つの Azure Web ロールでホストされる Web アプリです。私がトラブルシューティングしている問題はローカル マシンにあるため、次で始まるすべての URL でコンピューティング エミュレーターを使用します。

http://127.0.0.1:<port>/

クライアントには、CRUD アプリ内から呼び出した RestSharp を使用しています。私がデバッグしている POST リクエストの本文を入力するために使用されるクラスは次のとおりです。

データクラス

public class TestData
{
    public string Name { get; set; }
    public DateTime Date { get; set; }
    public Boolean IsTrue { get; set; }
}

...データをシリアル化し、文字列に変換するために使用されるコードは次のとおりです。RestSharp がシリアル化することは理解していますが、自分でシリアル化を行っているアプリケーション固有の理由が他にもあり、それが問題に関連しているとは思えません。それが問題に関連していることが判明した場合は、そこに行くことができますが、現時点では私の容疑者リストにはありません:

シリアル化方法

    private XmlDocument Serialize<T>( T theData )
    {
        XmlSerializer ser = new XmlSerializer( theData.GetType() );
        XmlDocument xml = new XmlDocument();

        using (MemoryStream stream = new MemoryStream())
        {
            ser.Serialize( stream, theData );
            stream.Flush();
            stream.Seek( 0, SeekOrigin.Begin );

            xml.Load( stream );
        }

        return xml;
    }

    private string GetStringFromXmlDocument( XmlDocument theDoc )
    {
        string result = null;

        using (var stringWriter = new StringWriter())
        using (var xmlTextWriter = XmlWriter.Create( stringWriter ))
        {
            theDoc.WriteTo( xmlTextWriter );
            xmlTextWriter.Flush();
            result = stringWriter.GetStringBuilder().ToString();
        }

        return result;
    }

...そして、データ クラスと上記のメソッドを使用する RestSharp クライアント コードは次のとおりです。

RestSharp クライアント

XmlDocument theSerializedData = Serialize( new TestData
                                   {
                                       Date = DateTime.Now,
                                       IsTrue = false,
                                       Name = "Oscar"
                                   } );

string theDataString = GetStringFromXmlDocument(theSerializedData);

RestClient client = new RestClient("http://127.0.0.1:7080/rest/testing");

RestRequest request = new RestRequest( "tests", Method.POST );

request.AddParameter( "text/xml", theTestData, ParameterType.RequestBody );

IRestResponse response = client.Execute( request );

if (response.StatusCode == HttpStatusCode.OK)
{
    ; // Make a happy face
}
else
{
    ; // Make a sad face
}

...ここに私が試した2つのルート構成があります:

ルート構成 #1

    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        routes.MapRoute(
        name: "RestTest",
        url: "rest/{controller}/{action}",
        defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
            );

        routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
        );

    }

ルート構成 #2

    public static void Register(HttpConfiguration config)
    {
        config.Routes.MapHttpRoute(
        name: "RestTest",
        routeTemplate: "rest/{controller}/{action}",
        defaults: new { controller = "Testing", action = "Tests" }
            );
    }

...そしてここにコントローラーがあります:

コントローラ

public class TestingController : ApiController
{
    [HttpPost]
    public void Tests(TestData theData)
    {
        bool isTru = theData.IsTrue;
    }
}

...Fiddler からキャプチャされた生のリクエストを次に示します (ホスト名は 127.0.0.1 に置き換えられます)。

HTTP リクエスト

  POST http://127.0.0.1:7080/rest/testing/tests HTTP/1.1
  Accept: application/json, application/xml, text/json, text/x-json, text/javascript, text/xml
  User-Agent: RestSharp 104.1.0.0
  Content-Type: text/xml
  Host: 127.0.0.1:7080
  Content-Length: 243
  Accept-Encoding: gzip, deflate

  <?xml version="1.0"?>
  <TestData xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <Name>Oscar</Name>
    <Date>2013-05-16T11:50:50.1270268-07:00</Date>
    <IsTrue>false</IsTrue>
  </TestData>

...そして、サービスからの 404 応答の要点は次のとおりです。

404 応答

The resource you are looking for (or one of its dependencies) could have been removed, had its name changed, or is temporarily unavailable.
Please review the following URL and make sure that it is spelled correctly.

Requested URL: /rest/testing/tests

[HttpException]: The controller for path '/rest/testing/tests' was not found or does not implement IController.
at System.Web.Mvc.DefaultControllerFactory.GetControllerInstance(RequestContext requestContext, Type controllerType)
at System.Web.Mvc.DefaultControllerFactory.CreateController(RequestContext requestContext, String controllerName)
at System.Web.Mvc.MvcHandler.ProcessRequestInit(HttpContextBase httpContext, IController& controller, IControllerFactory& factory)
at System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, Object state)
at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)
4

2 に答える 2

1

Api ルートとターゲット ApiControllers を登録するための「 routes.MapHttpRoute (」拡張機能を使用する必要があります。現在、MVC コントローラー用の MapRoute を使用しています。

于 2013-05-16T22:20:45.233 に答える