1

更新:私はBuild 2013にいましたが、Mark Simmsがこれを調べて、ルーターを離れるHTTPリクエストにリクエストに「Body」が含まれていることを確認しました。これは、GetがSBに到着し、パッケージ化されてルーティングされたことが原因であると彼は感じました。その後、パッケージはメッセージタイプとして再度管理されてから、再度送信されます。パッケージ化とルーティングの間に、プロパティはリクエストの本文に残されます。これは、「GET」のプロトコルに違反します。ただし、これはすべて、.NETまたはServiceBusのいずれかのMSフレームワーク内に存在します。本体は不変であるため(少なくともそれを変更する方法を見つけることができません)、唯一の手段は、要求を複製し、途中で元の要求を更新することです。

これは、AzureServiceBusエンドポイントからHTTPGET / POSTリクエストを受け取り、リレーチャネルを介してローカルワークステーションにダウンさせ、そこでURLを書き換えて、ローカルWebサービスに送信するルーティングアプリケーションのごく一部です。 。

これがインターフェースです-コントローラー/アクションURLへのあらゆるタイプの呼び出しを受信できるようにするためのジェネリック

  // The Router, and general concept of how to recieve from the SB and redirect was taken from
  // Tony Sneed Blog - which he documented here: http://blog.tonysneed.com/2012/04/24/roll-your-own-rest-ful-wcf-router/
  //
    [ServiceContract(Namespace = "urn:Twiddler")]
    public interface IRoutingService
    {
        [WebInvoke(UriTemplate = "")]
        [OperationContract(AsyncPattern = true, Action = "*", ReplyAction = "*")]
        IAsyncResult BeginProcessRequest(Message requestMessage, AsyncCallback asyncCallback, object asyncState);

        Message EndProcessRequest(IAsyncResult asyncResult);
    }
}

コードは次のとおりです。

[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall,
     AddressFilterMode = AddressFilterMode.Any, ValidateMustUnderstand = false)]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class RoutingService : IRoutingService, IDisposable
{
  private IRoutingService _client;

  /// <summary>
  /// when a message is received from the SB, it arrives here as simply a message - 
  /// </summary>
  /// <param name="requestMessage"></param>
  /// <param name="asyncCallback"></param>
  /// <param name="asyncState"></param>
  /// <returns></returns>
  public IAsyncResult BeginProcessRequest(Message requestMessage, AsyncCallback asyncCallback, object asyncState)
  {
    string RequestMessageAction = requestMessage.Headers.Action;

    IAsyncResult asyncResult = null;


    //if the full URI for the namespace does not match the one contructed in Twiddler, then pass it through - we have nothing to do with it!
    if (requestMessage.Headers.To.AbsoluteUri.Contains(Utilities.ServiceFormBridge.NameSpaceName) && requestMessage.Headers.To.AbsoluteUri.Contains(Utilities.ServiceFormBridge.EndPointName) == false)
      return asyncResult;

    //as the service bus will accept anything in terms of controllers and actions, we only need alter the DestinationAddress.Authority (host and port)
    var RewriteTheURL = requestMessage.Headers.To.AbsoluteUri.Replace(string.Format("http://{0}.servicebus.windows.net/{1}/", ServiceFormBridge.NameSpaceName, ServiceFormBridge.EndPointName), ServiceFormBridge.DestinationWebSite);

    Uri DestinationAddress = new Uri(RewriteTheURL);

    System.ServiceModel.ChannelFactory<IRoutingService> factory = null;

    factory = new ChannelFactory<IRoutingService>(new WebHttpBinding(), DestinationAddress.AbsoluteUri);

    WebHeaderCollection httpHeaders = WebOperationContext.Current.IncomingRequest.Headers;
    httpHeaders.Remove("Host");
    httpHeaders.Add("Host", DestinationAddress.Authority); //give it the new host that we are re-directing to

    httpHeaders.Remove("Connection");  //todo: not sure I need this, but without it there is an exception between Keep-Alive and Closed

    // Set factory and message address
    factory.Endpoint.Address = new EndpointAddress(DestinationAddress);
    requestMessage.Headers.To = DestinationAddress;


    _client = factory.CreateChannel();

    asyncResult = _client.BeginProcessRequest(requestMessage, asyncCallback, asyncState);

    return asyncResult;
  }
}

BeginProcessRequestで、例外が発生します。プロトコル違反:この動詞タイプのコンテンツ本文を送信できません

私が調査したところ、GETリクエストでは、リクエストの本文に何も含まれないことを理解しています。

私のコードはPOSTで機能するので、何らかの理由で本体に何かがあるとしか考えられません。

ただし、元のリクエストはServiceBusのURLを使用したブラウザからのGETであったため、本文に何かが含まれる理由がわかりません。

それで:

  1. 私は私に問題を引き起こしているコードで何かをしていると思っています-もしそうなら私は何を知りたいです!
  2. 着信リクエストに何かがある場合、違反が発生しないようにそれを削除するにはどうすればよいですか?
  3. 他の提案、コードの改善はありますか?
4

1 に答える 1

0

この属性を操作 [WebInvoke(UriTemplate = "")] に配置すると、デフォルトで POST がサポートされますが、PUT、DELETE などの他の動詞を指定するパラメーターを渡すことができます。ただし、GET は別の属性によってサポートされています。 [ウェブゲット]。ルーターに追加の操作を追加することをお勧めします。1 つは WebGet を使用し、もう 1 つは WebInvoke とさまざまな HTTP 動詞を使用します。

于 2013-03-11T02:06:00.290 に答える