5

我正在使用 ASP.NET MVC 3 平台开发一些 REST 资源。到目前为止,它很棒,我喜欢 MVC 3 的灵活性,用它构建 REST 服务是轻而易举的事。我遇到困难的一个领域是 Global.asax 中的路线限制。一方面,它们似乎永远无法正常工作(包括一个总是返回 404,即使输入绝对符合约束的要求......但那是另一个问题)。

其次,更重要的是,约束失败时返回的结果始终是 HTML 页面。假设约束有效,当这些 REST 服务的所有消费者都将接受数据类型(例如 application/json、text/xml,可能是 bson 等)时,结果是 HTML 确实会带来麻烦。我真的需要能够直接解决我们客户中的错误,而不是简单地炸毁和记录 html 以进行边带解析。

是否可以更改响应路由约束返回的内容?是否可以使返回的内容动态化,这样如果发出请求的客户端只接受应用程序/bson,我们可以生成可接受的响应,而不是简单地生成单一 mime 类型的预设响应?

4

2 回答 2

3

Errlusion在这里可能会有所帮助。

您可以编写一些自定义逻辑来检查 HTTPAccept标头和/或用于[SomeContext].Request.IsAjaxRequest()查看 JSON 或 BSON 是否适合返回 - 或者如果您愿意,只需为所有类型的请求返回 JSON 或 BSON。

于 2012-03-05T23:38:07.520 回答
3

关于返回代码错误而不是转到控制器,您必须实现自定义 RouteHandler。此链接恢复所有您可以关注的内容......并且您可以通过这种方式进行修改。关于“调整”返回类型......您可以在控制器中执行此操作。如果并且在某些情况下您返回 Json(...) 并且在其他情况下您返回 View 或 PartialView,则放置 som 就足够了。

然而,在控制器过滤器中这样做很好......!

我实现了一个控制过滤器,它允许控制器与客户端协商返回类型。我很简单...客户端只需在路由参数(一段 url 或查询字符串)中或通过发布包含此信息的字段来声明我想接收的类型。使用非常简单......如果没有来自客户端的信息,您的控制器可以返回一个“默认”返回类型的视图。然后过滤器在调用视图之前自动“更改”结果类型,将其转换为客户端所需的内容。过滤器处理的可能性是由客户端或 Json 选择名称的视图

代码在这里(它包含对客户端提供的“提示”的一些控制,以防止恶意用户的攻击):

public class AcceptViewHintAttribute : ActionFilterAttribute
{
    private JsonRequestBehavior jsBehavior;
    public AcceptViewHintAttribute(JsonRequestBehavior jsBehavior = JsonRequestBehavior.DenyGet)
    {
        this.jsBehavior = jsBehavior;
    }
    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        string hint = filterContext.RequestContext.HttpContext.Request.Params["ViewHint"];
        if (hint == null) hint = filterContext.RequestContext.RouteData.Values["ViewHint"] as string;
        if (!string.IsNullOrWhiteSpace(hint) && hint.Length<=100 && new Regex(@"^\w+$").IsMatch(hint) )
        {


                ViewResultBase res = filterContext.Result as ViewResultBase;
                if (res != null)
                {
                    if (hint == "json")
                    {
                        JsonResult jr = new JsonResult();
                        jr.Data = res.ViewData.Model;
                        jr.JsonRequestBehavior = jsBehavior;
                        filterContext.Result = jr;
                    }
                    else
                    {
                        res.ViewName = hint;
                    }
                }

        }
        base.OnActionExecuted(filterContext);
    }
}
于 2012-03-07T21:08:16.737 回答