Ключ PUT / POST / Коллекция значений для OpenRasta - PullRequest
0 голосов
/ 26 марта 2012

Как должен быть реализован обработчик OpenRasta, чтобы он мог принимать ID на основе шаблона URL вместе со словарем, Hashtable или NameValueCollection (мне все равно, какой)?

Мой URL-шаблон - "/fielddata/ndomcorrelationId‹".

Мое сообщение PUT:

PUT http://myhost/fielddata/39950 HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Content-Length: 14

X=123&Y=Abc

Я пробовал такой обработчик:

public class FieldDataHandler
{
  public void Put(string correlationId, NameValueCollection data)
  {
  }
}

Но получите исключение, подобное этому:

openrasta Verbose: 0 : Incoming host request for http://myhost/fielddata/39950
openrasta Verbose: 0 : Adding communication context data
openrasta Verbose: 0 : Found 1 operation(s) with a matching name.
openrasta Verbose: 0 : Found 0 operation(s) with matching [HttpOperation] attribute.
openrasta Information: 0 : Operation FieldDataHandler::Put(String correlationId, NameValueCollection data) selected with 2 required members and 0 optional members, with codec ApplicationXWwwFormUrlencodedKeyedValuesCodec with score 1,333333.
openrasta Error: 0 : An error has occurred and the processing of the request has stopped.

Exception:
System.InvalidOperationException: The operation is not ready for invocation.
   at OpenRasta.OperationModel.MethodBased.MethodBasedOperation.Invoke() in c:\Projects\OpenRasta\openrasta-stable\src\core\OpenRasta\OperationModel\MethodBased\MethodBasedOperation.cs:line 56
   at OpenRasta.OperationModel.Interceptors.OperationWithInterceptors.<Invoke>b__0() in c:\Projects\OpenRasta\openrasta-stable\src\core\OpenRasta\OperationModel\Interceptors\OperationWithInterceptors.cs:line 47
   at OpenRasta.OperationModel.Interceptors.OperationWithInterceptors.Invoke() in c:\Projects\OpenRasta\openrasta-stable\src\core\OpenRasta\OperationModel\Interceptors\OperationWithInterceptors.cs:line 52
   at OpenRasta.OperationModel.OperationExecutor.Execute(IEnumerable`1 operations) in c:\Projects\OpenRasta\openrasta-stable\src\core\OpenRasta\OperationModel\OperationExecutor.cs:line 14
   at OpenRasta.Pipeline.Contributors.OperationInvokerContributor.ExecuteOperations(ICommunicationContext context) in c:\Projects\OpenRasta\openrasta-stable\src\core\OpenRasta\Pipeline\Contributors\OperationInvokerContributor.cs:line 29
   at OpenRasta.Pipeline.PipelineRunner.ExecuteContributor(ICommunicationContext context, ContributorCall call) in c:\Projects\OpenRasta\openrasta-stable\src\core\OpenRasta\Pipeline\PipelineRunner.cs:line 187
openrasta Information: 0 : Executing OperationResult OperationResult: type=InternalServerError, statusCode=500.

1 Ответ

0 голосов
/ 29 марта 2012

Закончилось исправление этой ошибки путем создания нового кодека для доменного типа ресурса (вместо универсального типа NameValueCollection), а затем выполнения сериализованной (де) сериализации в форме другим способом.

Сам кодек выглядит так:

[MediaType("application/x-www-form-urlencoded")]
public class RestFieldDataCodec : IMediaTypeWriter, IMediaTypeReader
{
  public void WriteTo(object entity, IHttpEntity response, string[] codecParameters)
  {
    RestFieldData data = (RestFieldData)entity;

    using (TextWriter writer = new StreamWriter(response.Stream))
    {
      FormUrlEncodingSerializer serializer = new FormUrlEncodingSerializer(typeof(NameValueCollection));
      serializer.Serialize(writer, data.Data);
    }
  }


  public object ReadFrom(IHttpEntity request, IType destinationType, string destinationName)
  {
    using (TextReader reader = new StreamReader(request.Stream))
    {
      FormUrlEncodingSerializer serializer = new FormUrlEncodingSerializer(typeof(NameValueCollection));
      NameValueCollection keyValueData = (NameValueCollection)serializer.Deserialize(reader);
      return new RestFieldData
      {
        Data = keyValueData
      };
    }
  }


  public object Configuration { get; set; }
}

А тип ресурса довольно прост:

public class RestFieldData
{
  public NameValueCollection Data { get; set; }
}

Класс FormUrlEncodingSerializer относится к https://github.com/JornWildt/Ramone

Метод обработчика закончился так:

public void Put(string correlationId, RestFieldData payload)
{
  ...
}
...