// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information. using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Net.Http; using System.Net.Http.Formatting; using System.Reflection; using System.Threading.Tasks; using System.Web.Http.Controllers; namespace Microsoft.Web.Http.Data { /// /// This descriptor translates a direct CUD action invocation into a call to /// Submit. This descriptor wraps the actual action, intercepting the execution /// to do the transformation. /// internal sealed class SubmitProxyActionDescriptor : ReflectedHttpActionDescriptor { private UpdateActionDescriptor _updateAction; public SubmitProxyActionDescriptor(UpdateActionDescriptor updateAction) : base(updateAction.ControllerDescriptor, updateAction.ControllerDescriptor.ControllerType.GetMethod("Submit", BindingFlags.Instance | BindingFlags.Public)) { _updateAction = updateAction; } public override string ActionName { get { return _updateAction.ActionName; } } public override Type ReturnType { get { return typeof(HttpResponseMessage); } } public override Collection GetParameters() { return _updateAction.GetParameters(); } [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "Caller is responsible for the lifetime of the object")] public override Task ExecuteAsync(HttpControllerContext controllerContext, IDictionary arguments) { return TaskHelpers.RunSynchronously(() => { // create the changeset object entity = arguments.Single().Value; // there is only a single parameter - the entity being submitted ChangeSetEntry[] changeSetEntries = new ChangeSetEntry[] { new ChangeSetEntry { Id = 1, ActionDescriptor = _updateAction, Entity = entity, Operation = _updateAction.ChangeOperation } }; ChangeSet changeSet = new ChangeSet(changeSetEntries); changeSet.SetEntityAssociations(); DataController controller = (DataController)controllerContext.Controller; if (!controller.Submit(changeSet) && controller.ActionContext.Response != null) { // If the submit failed due to an authorization failure, // return the authorization response directly return controller.ActionContext.Response; } // return the entity entity = changeSet.ChangeSetEntries[0].Entity; // REVIEW does JSON make sense here? return new HttpResponseMessage() { Content = new ObjectContent(_updateAction.EntityType, entity, new JsonMediaTypeFormatter()) }; }); } } }