如何使用ASP.NET MVC Web API OData链接到Razor中的OData集合

时间:2021-06-10 19:34:45

I have an ASP.NET MVC 4 app that i'm incorporating an OData API into. This is running the 2012.2 stuff with the larger OData support.

我有一个ASP.NET MVC 4应用程序,我正在将OData API合并到其中。这是运行具有更大OData支持的2012.2内容。

I did not use a separate area for this...that might have been a mistake but my app is small and area seemed overkill.

我没有使用单独的区域...这可能是一个错误,但我的应用程序很小,区域似乎有点过分。

I've got my controllers setup correctly and an example path to my Segments collection (segments is a type in my domain) is "/odata/Segments". This loads as expected and is working.

我的控制器设置正确,我的Segments集合的示例路径(段是我的域中的类型)是“/ odata / Segments”。这按预期加载并正在工作。

On my homepage i'm trying to add a link to this resource using Razor's Html.ActionLink (or RouteLink) but it seems the OData controllers layout doesn't quite work with those methods because the controllers are prefixed with "odata" when registered in WebAPIConfig:

在我的主页上,我正在尝试使用Razor的Html.ActionLink(或RouteLink)添加此资源的链接,但似乎OData控制器布局不能完全使用这些方法,因为控制器在注册时以“odata”为前缀WebAPIConfig:

config.Routes.MapODataRoute("OData Route", "odata", model );

I can trick the method to construct the correct url by pretending there's an odata controller when there certainly isn't one (as far as i know) with something like this:

我可以通过假装有一个odata控制器来欺骗该方法来构造正确的url,当时肯定没有一个(据我所知)这样的东西:

@Html.RouteLink("Segments", "Segments", "odata")

but that seems like a hack.

但这似乎是一个黑客。

I don't quite understand the ASP.NET routing plumbing well enough to understand how that prefix passed to MapODataRoute is being incorporated into the MVC chain so that i can use the "right" razor method the "right" way.

我不太了解ASP.NET路由管道,足以理解传递给MapODataRoute的前缀是如何被合并到MVC链中的,这样我就能以“正确”的方式使用“正确”的剃刀方法。

just for kicks, here's my SegmentsController:

只是为了踢,这是我的SegmentsController:

public class SegmentsController : EntitySetController<Segment, long>
{

    private MarketerDB db = new MarketerDB();

    // GET api/segments
    override public IQueryable<Segment> Get()
    {
        return db.Segments.AsQueryable();
    }


    protected override Segment GetEntityByKey(long key)
    {
        return db.Segments.Find(key);
    }


    public IQueryable<Affiliate> GetAffiliates([FromODataUri] long key)
    {
        return this.GetEntityByKey(key).Affiliates.AsQueryable();
    }

    protected override void Dispose(bool disposing)
    {
        db.Dispose();
        base.Dispose(disposing);
    }
}

1 个解决方案

#1


8  

We have an ODataLink method on System.Web.Http.UrlHelper but we forgot to add one to the MVC System.Web.Mvc.UrlHelper. Till we add it, you can use this extension method,

我们在System.Web.Http.UrlHelper上有一个ODataLink方法,但我们忘了在MVC System.Web.Mvc.UrlHelper中添加一个。直到我们添加它,您可以使用此扩展方法,

namespace System.Web.Mvc
{
    public static class UrlHelperExtensions
    {
        private static IODataPathHandler _pathHandler = new DefaultODataPathHandler();

        public static string ODataUrl(this UrlHelper urlHelper, string routeName, params ODataPathSegment[] segments)
        {
            string odataPath = _pathHandler.Link(new ODataPath(segments));
            return urlHelper.HttpRouteUrl(
                routeName,
                new RouteValueDictionary() { { ODataRouteConstants.ODataPath, odataPath } });
        }
    }
}

and call it from your razor views by doing something like (assuming there is an entityset customers and you want to put the navigation link to orders on customers(42)),

通过做类似的事情从你的剃刀视图中调用它(假设有一个实体集客户,你想把导航链接放到客户的订单上(42)),

@Url.ODataUrl("odata", new EntitySetPathSegment("customers"), new KeyValuePathSegment("42"), new NavigationPathSegment("orders"))

Make sure you have an @using System.Web.Http.OData.Routing directive in your razor view.

确保你的剃刀视图中有一个@using System.Web.Http.OData.Routing指令。

#1


8  

We have an ODataLink method on System.Web.Http.UrlHelper but we forgot to add one to the MVC System.Web.Mvc.UrlHelper. Till we add it, you can use this extension method,

我们在System.Web.Http.UrlHelper上有一个ODataLink方法,但我们忘了在MVC System.Web.Mvc.UrlHelper中添加一个。直到我们添加它,您可以使用此扩展方法,

namespace System.Web.Mvc
{
    public static class UrlHelperExtensions
    {
        private static IODataPathHandler _pathHandler = new DefaultODataPathHandler();

        public static string ODataUrl(this UrlHelper urlHelper, string routeName, params ODataPathSegment[] segments)
        {
            string odataPath = _pathHandler.Link(new ODataPath(segments));
            return urlHelper.HttpRouteUrl(
                routeName,
                new RouteValueDictionary() { { ODataRouteConstants.ODataPath, odataPath } });
        }
    }
}

and call it from your razor views by doing something like (assuming there is an entityset customers and you want to put the navigation link to orders on customers(42)),

通过做类似的事情从你的剃刀视图中调用它(假设有一个实体集客户,你想把导航链接放到客户的订单上(42)),

@Url.ODataUrl("odata", new EntitySetPathSegment("customers"), new KeyValuePathSegment("42"), new NavigationPathSegment("orders"))

Make sure you have an @using System.Web.Http.OData.Routing directive in your razor view.

确保你的剃刀视图中有一个@using System.Web.Http.OData.Routing指令。