Skip to content

Commit

Permalink
add support
Browse files Browse the repository at this point in the history
  • Loading branch information
mirsking committed Sep 12, 2016
1 parent b930dfb commit 68e14c4
Show file tree
Hide file tree
Showing 4 changed files with 334 additions and 54 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,206 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Web.Http;
using System.Web.OData;
using System.Web.OData.Extensions;
using System.Web.OData.Routing;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.OData.Edm;
using Microsoft.OData.Service.Sample.TrippinInMemory.Api;
using Microsoft.OData.Service.Sample.TrippinInMemory.Models;
using Microsoft.Restier.Core;

namespace Microsoft.OData.Service.Sample.TrippinInMemory.Controllers
{
public class PeopleController : ODataController
{
private TrippinApi _api;
private TrippinApi Api
{
get
{
if (_api == null)
{
_api = (TrippinApi)this.Request.GetRequestContainer().GetService<ApiBase>();
}

return _api;
}
}

/// <summary>
/// Restier only supports put and post entity set.
/// Use property name to simulate the bound action.
/// </summary>
/// <param name="key">Key of people entity set, parsed from uri.</param>
/// <param name="name">The value of last name to be updated.</param>
/// <returns><see cref="IHttpActionResult"></returns>
[HttpPut]
[ODataRoute("People({key})/LastName")]
public IHttpActionResult UpdatePersonLastName([FromODataUri]string key, [FromBody] string name)
{
var person = Api.People.Single(p => p.UserName == key);
if (Api.UpdatePersonLastName(person, name))
{
return Ok();
}
else
{
return NotFound();
}
}

[HttpGet]
[ODataRoute("People({key})/Friends/$ref")]
public IHttpActionResult GetRefToFriendsFromPeople([FromODataUri]string key)
{
var entity = Api.People.FirstOrDefault(p => p.UserName == key);
if (entity == null)
{
return NotFound();
}

var friends = entity.Friends;
if (friends == null)
{
return NotFound();
}

var serviceRootUri = Helpers.GetServiceRootUri(Request);
IList<Uri> uris = new List<Uri>();
foreach (var friend in friends)
{
uris.Add(new Uri(string.Format("{0}/People('{1}')", serviceRootUri, friend.UserName)));
}

return Ok(uris);
}

[HttpGet]
[ODataRoute("People({key})/Friends({key2})/$ref")]
public IHttpActionResult GetRefToOneFriendFromPeople([FromODataUri]string key, [FromODataUri]string key2)
{
var entity = Api.People.FirstOrDefault(p => p.UserName == key);
if (entity == null)
{
return NotFound();
}

var friends = entity.Friends;
if (friends == null)
{
return NotFound();
}

var serviceRootUri = Helpers.GetServiceRootUri(Request);
if (friends.All(t => t.UserName != key2))
{
return NotFound();
}

return Ok(new Uri(string.Format("{0}/People('{1}')", serviceRootUri, key2)));
}

[HttpPost]
[ODataRoute("People({key})/Friends/$ref")]
public IHttpActionResult CreateRefForFriendsToPeople([FromODataUri]string key, [FromBody] Uri link)
{
var entity = Api.People.FirstOrDefault(p => p.UserName == key);
if (entity == null)
{
return NotFound();
}

var relatedKey = Helpers.GetKeyFromUri<string>(Request, link);
var friend = Api.People.SingleOrDefault(t => t.UserName == relatedKey);
if (friend == null)
{
return NotFound();
}

entity.Friends.Add(friend);
return StatusCode(HttpStatusCode.NoContent);
}

[HttpDelete]
[ODataRoute("People({key})/Friends({relatedKey})/$ref")]
public IHttpActionResult DeleteRefToFriendsFromPeople([FromODataUri]string key, [FromODataUri]string relatedKey)
{
var entity = Api.People.FirstOrDefault(p => p.UserName == key);
if (entity == null)
{
return NotFound();
}

var friend = entity.Friends.SingleOrDefault(t => t.UserName == relatedKey);
if (friend == null)
{
return NotFound();
}

entity.Friends.Remove(friend);
return StatusCode(HttpStatusCode.NoContent);
}

[HttpGet]
[ODataRoute("People({key})/BestFriend/$ref")]
public IHttpActionResult GetRefToBestFriendFromPeople([FromODataUri]string key)
{
var entity = Api.People.FirstOrDefault(p => p.UserName == key);
if (entity == null)
{
return NotFound();
}

var friend = entity.BestFriend;
if (friend == null)
{
return NotFound();
}

var serviceRootUri = Helpers.GetServiceRootUri(Request);
var uri = new Uri(string.Format("{0}/People('{1}')", serviceRootUri, friend.UserName));
return Ok(uri);
}

[HttpPut]
[ODataRoute("People({key})/BestFriend/$ref")]
public IHttpActionResult CreateRefForBestFriendToPeople([FromODataUri]string key, [FromBody] Uri link)
{
var entity = Api.People.FirstOrDefault(p => p.UserName == key);
if (entity == null)
{
return NotFound();
}

var relatedKey = Helpers.GetKeyFromUri<string>(Request, link);
var friend = Api.People.SingleOrDefault(t => t.UserName == relatedKey);
if (friend == null)
{
return NotFound();
}

entity.BestFriend = friend;
return StatusCode(HttpStatusCode.NoContent);
}

[HttpDelete]
[ODataRoute("People({key})/BestFriend/$ref")]
public IHttpActionResult DeleteRefToBestFriendFromPeople([FromODataUri]string key)
{
var entity = Api.People.FirstOrDefault(p => p.UserName == key);
if (entity == null)
{
return NotFound();
}

entity.BestFriend = null;
return StatusCode(HttpStatusCode.NoContent);
}
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Net.Http;
using System.Text.RegularExpressions;
using System.Web;
using System.Web.Http.Routing;
using System.Web.OData.Extensions;
using System.Web.OData.Routing;
using Microsoft.OData.UriParser;

namespace Microsoft.OData.Service.Sample.TrippinInMemory
{
public static class Helpers
{
public static TKey GetKeyFromUri<TKey>(HttpRequestMessage request, Uri uri)
{
if (uri == null)
{
throw new ArgumentNullException("uri");
}

string serviceRoot = GetServiceRootUri(request);
uri = RebuildUri(uri, serviceRoot);
var pathHandler = (IODataPathHandler)request.GetRequestContainer().GetService(typeof(IODataPathHandler));
var odataPath = pathHandler.Parse(serviceRoot, uri.LocalPath, request.GetRequestContainer());

var keySegment = odataPath.Segments.OfType<KeySegment>().FirstOrDefault();
if (keySegment == null)
{
throw new InvalidOperationException("The link does not contain a key.");
}

var value = keySegment.Keys.FirstOrDefault().Value;
return (TKey)value;
}

public static string GetSessionIdFromString(string str)
{
var match = Regex.Match(str, @"/\(S\((\w+)\)\)");
if (match.Success)
{
return match.Groups[1].Value;
}

return default(string);
}

public static string GetServiceRootUri(HttpRequestMessage request)
{
var urlHelper = request.GetUrlHelper() ?? new UrlHelper(request);
var pathHandler = (IODataPathHandler)request.GetRequestContainer().GetService(typeof(IODataPathHandler));
string serviceRoot = urlHelper.CreateODataLink(
request.ODataProperties().RouteName,
pathHandler, new List<ODataPathSegment>());
return serviceRoot;
}

public static Uri RebuildUri(Uri original, string serviceRoot)
{
var serviceRootSessionId = GetSessionIdFromString(serviceRoot);
if (serviceRootSessionId == null)
{
throw new ArgumentNullException("Key in request URI is null.");
}

var originalSessionId = GetSessionIdFromString(original.ToString());
if (originalSessionId == null)
{
var uri = default(Uri);
var builder = new UriBuilder(original.Scheme, original.Host, original.Port,
HttpContext.Current.Request.ApplicationPath);
var beforeSessionSegement = new Uri(builder.ToString(), UriKind.Absolute).AbsoluteUri;
var afterSessionSegment = original.AbsoluteUri.Substring(beforeSessionSegement.Length);

var sessionSegment = string.Format("(S({0}))", HttpContext.Current.Session.SessionID);
var path = CombineUriPaths(beforeSessionSegement, sessionSegment);
path = CombineUriPaths(path, afterSessionSegment);
uri = new Uri(path);

var uriBuilder = new UriBuilder(uri);
var baseAddressUri = new Uri(serviceRoot, UriKind.Absolute);
uriBuilder.Host = baseAddressUri.Host;
uri = new Uri(uriBuilder.ToString());

return uri;
}

if (originalSessionId.Equals(serviceRootSessionId))
{
return original;
}

throw new InvalidOperationException(
String.Format(
CultureInfo.InvariantCulture,
"Key '{0}' in request is not the same with that '{1}' in service root URI.",
originalSessionId,
serviceRootSessionId));
}

private static string CombineUriPaths(string path1, string path2)
{
if (path1.EndsWith("/", StringComparison.OrdinalIgnoreCase))
{
if (path2.StartsWith("/", StringComparison.OrdinalIgnoreCase))
{
path2 = path2.Substring(1);
}
}
else
{
if (!path2.StartsWith("/", StringComparison.OrdinalIgnoreCase))
{
path2 = "/" + path2;
}
}

return path1 + path2;
}
}
}
Loading

0 comments on commit 68e14c4

Please sign in to comment.