我的情况是:
OpenRasta.Codecs.IMediaTypeReader
的自定义实现。这会将JSON有效负载转换为处理程序所期望的POCO。Newtonsoft.Json.JsonReaderException: After parsing a value an unexpected character was encountered: ". Line 4, position 5.
如果修改编解码器以捕获JsonReaderException
并返回Missing.Value
,类似于Implementing a codec wiki,则客户端会收到HTTP 500 - 内部服务器错误。响应正文还描述了以下异常:
System.InvalidOperationException: The operation is not ready for invocation.
at OpenRasta.OperationModel.MethodBased.MethodBasedOperation.Invoke()
at OpenRasta.OperationModel.Interceptors.OperationWithInterceptors.<Invoke>b__0()
at OpenRasta.OperationModel.Interceptors.OperationWithInterceptors.Invoke()
at OpenRasta.OperationModel.OperationExecutor.Execute(IEnumerable`1 operations)
at OpenRasta.Pipeline.Contributors.OperationInvokerContributor.ExecuteOperations(ICommunicationContext context)
at OpenRasta.Pipeline.PipelineRunner.ExecuteContributor(ICommunicationContext context, ContributorCall call)
我应该如何修改我的应用程序:
答案 0 :(得分:3)
以上是上述答案的一个小变化 - 这次是根据操作结果数据选择编解码器。
IConfigurationSource
内:
using (OpenRastaConfiguration.Manual)
{
ResourceSpace.Uses.PipelineContributor<ErrorCheckingContributor>();
ResourceSpace.Has.ResourcesOfType<ApplicationError>()
.WithoutUri
.TranscodedBy<ApplicationErrorCodec>();
// Or use a generic JSON serializer like this:
// .AsJsonDataContract();
// Other configuration here
}
现在ErrorCheckingContributor
看起来像这样:
public class ErrorCheckingContributor : IPipelineContributor
{
public void Initialize(IPipeline pipelineRunner)
{
pipelineRunner
.Notify(CheckRequestDecoding)
.After<KnownStages.IOperationResultInvocation>()
.And.Before<KnownStages.ICodecResponseSelection>();
}
private static PipelineContinuation CheckRequestDecoding(ICommunicationContext context)
{
if (context.ServerErrors.Count == 0)
{
return PipelineContinuation.Continue;
}
Error err = context.ServerErrors[0];
// Get a suitable message (err.Message contains stack traces, so try to avoid that)
string msg = err.Title;
if (msg == null && err.Exception != null)
msg = err.Exception.Message;
if (msg == null)
msg = err.Message;
// Create instance of an error information resource which is specific for the application
// - This one is rather simple and only contains a copy of the message
ApplicationError error = new ApplicationError(msg);
// Set operation result to be "400 Bad Request" and remove errors
context.OperationResult = new OperationResult.BadRequest { ResponseResource = error };
context.ServerErrors.Clear();
// Render immediately without starting any handlers
return PipelineContinuation.RenderNow;
}
}
班级ApplicationError
是:
public class ApplicationError
{
public string Message { get; set; }
public ApplicationError(string message)
{
Message = message;
}
}
最后,我们需要ApplicationErrorCodec
的编解码器ApplicationError
。这与任何其他IMediaTypeWriter编解码器没有什么不同,但很大程度上取决于您预期的响应媒体类型。有关示例,请参阅https://github.com/openrasta/openrasta/wiki/Implementing-a-Codec。
答案 1 :(得分:2)
在Google网上论坛上找到包含所有答案的this主题后,我当前的实现看起来像这样。
在IConfigurationSource
的实施中:
using (OpenRastaConfiguration.Manual)
{
ResourceSpace.Uses.PipelineContributor<ErrorCheckingContributor>();
// Other configuration here
}
然后ErrorCheckingContributor
看起来像这样:
public class ErrorCheckingContributor : IPipelineContributor
{
public void Initialize(IPipeline pipelineRunner)
{
pipelineRunner
.Notify(CheckRequestDecoding)
.After<KnownStages.IOperationResultInvocation>()
.And.Before<KnownStages.ICodecResponseSelection>();
}
private static PipelineContinuation CheckRequestDecoding(ICommunicationContext context)
{
if (context.ServerErrors.Count == 0)
{
return PipelineContinuation.Continue;
}
var first = context.ServerErrors[0];
if (first.Exception is Newtonsoft.Json.JsonReaderException)
{
context.Response.Entity.ContentType = MediaType.TextPlain;
context.Response.Entity.ContentLength = first.Exception.Message.Length;
using (var sw = new StreamWriter(context.Response.Entity.Stream))
{
sw.Write(first.Exception.Message);
}
}
return PipelineContinuation.Continue;
}
}
上面有一些事情需要注意:
JsonReaderException
,它也会在此处理。context.OperationResult
设置为context.ServerErrors
- 但它没有通过编解码器。