diff --git a/src/csharp/Grpc.Core/Internal/AsyncCall.cs b/src/csharp/Grpc.Core/Internal/AsyncCall.cs
index 24b75d16686bd791c626d4c9bc18259f93039879..660ad1c32a4360fc335ff3b26d6b2296614de11c 100644
--- a/src/csharp/Grpc.Core/Internal/AsyncCall.cs
+++ b/src/csharp/Grpc.Core/Internal/AsyncCall.cs
@@ -302,7 +302,9 @@ namespace Grpc.Core.Internal
                 return;
             }
 
-            var status = ctx.GetReceivedStatus();
+            var fullStatus = ctx.GetReceivedStatusOnClient();
+            var status = fullStatus.Status;
+
             if (status.StatusCode != StatusCode.OK)
             {
                 unaryResponseTcs.SetException(new RpcException(status));
@@ -321,7 +323,8 @@ namespace Grpc.Core.Internal
         /// </summary>
         private void HandleFinished(bool success, BatchContextSafeHandle ctx)
         {
-            var status = ctx.GetReceivedStatus();
+            var fullStatus = ctx.GetReceivedStatusOnClient();
+            var status = fullStatus.Status;
 
             AsyncCompletionDelegate<TResponse> origReadCompletionDelegate = null;
             lock (myLock)
diff --git a/src/csharp/Grpc.Core/Internal/BatchContextSafeHandle.cs b/src/csharp/Grpc.Core/Internal/BatchContextSafeHandle.cs
index bfd88a0940b9275d66640d91da5040a160061002..6a2add54db583d7f897f5a233ab372e8f58e103a 100644
--- a/src/csharp/Grpc.Core/Internal/BatchContextSafeHandle.cs
+++ b/src/csharp/Grpc.Core/Internal/BatchContextSafeHandle.cs
@@ -38,7 +38,6 @@ using Grpc.Core;
 namespace Grpc.Core.Internal
 {
     /// <summary>
-    /// Not owned version of 
     /// grpcsharp_batch_context
     /// </summary>
     internal class BatchContextSafeHandle : SafeHandleZeroIsInvalid
@@ -47,7 +46,7 @@ namespace Grpc.Core.Internal
         static extern BatchContextSafeHandle grpcsharp_batch_context_create();
 
         [DllImport("grpc_csharp_ext.dll")]
-        static extern IntPtr grpcsharp_batch_context_receive_initial_metadata(BatchContextSafeHandle ctx);
+        static extern IntPtr grpcsharp_batch_context_recv_initial_metadata(BatchContextSafeHandle ctx);
 
         [DllImport("grpc_csharp_ext.dll")]
         static extern IntPtr grpcsharp_batch_context_recv_message_length(BatchContextSafeHandle ctx);
@@ -70,6 +69,12 @@ namespace Grpc.Core.Internal
         [DllImport("grpc_csharp_ext.dll")]
         static extern IntPtr grpcsharp_batch_context_server_rpc_new_method(BatchContextSafeHandle ctx);  // returns const char*
 
+        [DllImport("grpc_csharp_ext.dll")]
+        static extern IntPtr grpcsharp_batch_context_server_rpc_new_host(BatchContextSafeHandle ctx);  // returns const char*
+
+        [DllImport("grpc_csharp_ext.dll")]
+        static extern Timespec grpcsharp_batch_context_server_rpc_new_deadline(BatchContextSafeHandle ctx);
+
         [DllImport("grpc_csharp_ext.dll")]
         static extern IntPtr grpcsharp_batch_context_server_rpc_new_request_metadata(BatchContextSafeHandle ctx);
 
@@ -96,24 +101,26 @@ namespace Grpc.Core.Internal
             }
         }
 
+        // Gets data of recv_initial_metadata completion.
         public Metadata GetReceivedInitialMetadata()
         {
-            IntPtr metadataArrayPtr = grpcsharp_batch_context_receive_initial_metadata(this);
+            IntPtr metadataArrayPtr = grpcsharp_batch_context_recv_initial_metadata(this);
             return MetadataArraySafeHandle.ReadMetadataFromPtrUnsafe(metadataArrayPtr);
         }
-
-        public Status GetReceivedStatus()
+            
+        // Gets data of recv_status_on_client completion.
+        public ClientSideStatus GetReceivedStatusOnClient()
         {
             string details = Marshal.PtrToStringAnsi(grpcsharp_batch_context_recv_status_on_client_details(this));
-            return new Status(grpcsharp_batch_context_recv_status_on_client_status(this), details);
-        }
+            var status = new Status(grpcsharp_batch_context_recv_status_on_client_status(this), details);
 
-        public Metadata GetReceivedStatusTrailingMetadata()
-        {
             IntPtr metadataArrayPtr = grpcsharp_batch_context_recv_status_on_client_trailing_metadata(this);
-            return MetadataArraySafeHandle.ReadMetadataFromPtrUnsafe(metadataArrayPtr);
+            var metadata = MetadataArraySafeHandle.ReadMetadataFromPtrUnsafe(metadataArrayPtr);
+
+            return new ClientSideStatus(status, metadata);
         }
 
+        // Gets data of recv_message completion.
         public byte[] GetReceivedMessage()
         {
             IntPtr len = grpcsharp_batch_context_recv_message_length(this);
@@ -126,22 +133,22 @@ namespace Grpc.Core.Internal
             return data;
         }
 
-        public CallSafeHandle GetServerRpcNewCall()
+        // Gets data of server_rpc_new completion.
+        public ServerRpcNew GetServerRpcNew()
         {
-            return grpcsharp_batch_context_server_rpc_new_call(this);
-        }
+            var call = grpcsharp_batch_context_server_rpc_new_call(this);
 
-        public string GetServerRpcNewMethod()
-        {
-            return Marshal.PtrToStringAnsi(grpcsharp_batch_context_server_rpc_new_method(this));
-        }
+            var method = Marshal.PtrToStringAnsi(grpcsharp_batch_context_server_rpc_new_method(this));
+            var host = Marshal.PtrToStringAnsi(grpcsharp_batch_context_server_rpc_new_host(this));
+            var deadline = grpcsharp_batch_context_server_rpc_new_deadline(this);
 
-        public Metadata GetServerRpcNewRequestMetadata()
-        {
             IntPtr metadataArrayPtr = grpcsharp_batch_context_server_rpc_new_request_metadata(this);
-            return MetadataArraySafeHandle.ReadMetadataFromPtrUnsafe(metadataArrayPtr);
+            var metadata = MetadataArraySafeHandle.ReadMetadataFromPtrUnsafe(metadataArrayPtr);
+
+            return new ServerRpcNew(call, method, host, deadline, metadata);
         }
 
+        // Gets data of receive_close_on_server completion.
         public bool GetReceivedCloseOnServerCancelled()
         {
             return grpcsharp_batch_context_recv_close_on_server_cancelled(this) != 0;
@@ -153,4 +160,97 @@ namespace Grpc.Core.Internal
             return true;
         }
     }
+
+    /// <summary>
+    /// Status + metadata received on client side when call finishes.
+    /// (when receive_status_on_client operation finishes).
+    /// </summary>
+    internal struct ClientSideStatus
+    {
+        readonly Status status;
+        readonly Metadata trailers;
+
+        public ClientSideStatus(Status status, Metadata trailers)
+        {
+            this.status = status;
+            this.trailers = trailers;
+        }
+
+        public Status Status
+        {
+            get
+            {
+                return this.status;
+            }    
+        }
+
+        public Metadata Trailers
+        {
+            get
+            {
+                return this.trailers;
+            }
+        }
+    }
+
+    /// <summary>
+    /// Details of a newly received RPC.
+    /// </summary>
+    internal struct ServerRpcNew
+    {
+        readonly CallSafeHandle call;
+        readonly string method;
+        readonly string host;
+        readonly Timespec deadline;
+        readonly Metadata requestMetadata;
+
+        public ServerRpcNew(CallSafeHandle call, string method, string host, Timespec deadline, Metadata requestMetadata)
+        {
+            this.call = call;
+            this.method = method;
+            this.host = host;
+            this.deadline = deadline;
+            this.requestMetadata = requestMetadata;
+        }
+
+        public CallSafeHandle Call
+        {
+            get
+            {
+                return this.call;
+            }
+        }
+
+        public string Method
+        {
+            get
+            {
+                return this.method;
+            }
+        }
+
+        public string Host
+        {
+            get
+            {
+                return this.host;
+            }
+        }
+
+        public Timespec Deadline
+        {
+            get
+            {
+                return this.deadline;
+            }
+        }
+
+        public Metadata RequestMetadata
+        {
+            get
+            {
+                return this.requestMetadata;
+            }
+        }
+    }
 }
\ No newline at end of file
diff --git a/src/csharp/Grpc.Core/Internal/MetadataArraySafeHandle.cs b/src/csharp/Grpc.Core/Internal/MetadataArraySafeHandle.cs
index e17eb89abc798ae5013850011c730c9d874d9d63..ede85fb7f23683da9c4acc2494f9d69d210c4a87 100644
--- a/src/csharp/Grpc.Core/Internal/MetadataArraySafeHandle.cs
+++ b/src/csharp/Grpc.Core/Internal/MetadataArraySafeHandle.cs
@@ -34,8 +34,6 @@ using System.Threading.Tasks;
 
 namespace Grpc.Core.Internal
 {
-    
-
     /// <summary>
     /// grpc_metadata_array from <grpc/grpc.h>
     /// </summary>
diff --git a/src/csharp/Grpc.Core/Server.cs b/src/csharp/Grpc.Core/Server.cs
index cbf77196cf3193546465b4bbb1f851470c17084d..22f0e8973a370858c8e2e31264f675d70f1d506d 100644
--- a/src/csharp/Grpc.Core/Server.cs
+++ b/src/csharp/Grpc.Core/Server.cs
@@ -242,13 +242,12 @@ namespace Grpc.Core
         {
             // TODO: handle error
 
-            CallSafeHandle call = ctx.GetServerRpcNewCall();
-            string method = ctx.GetServerRpcNewMethod();
+            ServerRpcNew newRpc = ctx.GetServerRpcNew();
 
             // after server shutdown, the callback returns with null call
-            if (!call.IsInvalid)
+            if (!newRpc.Call.IsInvalid)
             {
-                Task.Run(async () => await InvokeCallHandler(call, method));
+                Task.Run(async () => await InvokeCallHandler(newRpc.Call, newRpc.Method));
             }
 
             AllowOneRpc();
diff --git a/src/csharp/ext/grpc_csharp_ext.c b/src/csharp/ext/grpc_csharp_ext.c
index d8996ae7a9918c59d07ef95ca0df1a0dcb546e63..cfd96d15f1d0c308b49b31f4f0711aa5becbf1e8 100644
--- a/src/csharp/ext/grpc_csharp_ext.c
+++ b/src/csharp/ext/grpc_csharp_ext.c
@@ -175,7 +175,7 @@ grpcsharp_metadata_array_count(grpc_metadata_array *array) {
 GPR_EXPORT const grpc_metadata *GPR_CALLTYPE
 grpcsharp_metadata_array_get(grpc_metadata_array *array, size_t index) {
   GPR_ASSERT(index < array->count);
-  return array->metadata[index];
+  return &(array->metadata[index]);
 }
 
 /* Move contents of metadata array */
@@ -230,7 +230,7 @@ GPR_EXPORT void GPR_CALLTYPE grpcsharp_batch_context_destroy(grpcsharp_batch_con
 }
 
 GPR_EXPORT const grpc_metadata_array *GPR_CALLTYPE
-grpcsharp_batch_context_receive_initial_metadata(
+grpcsharp_batch_context_recv_initial_metadata(
     const grpcsharp_batch_context *ctx) {
   return &(ctx->recv_initial_metadata);
 }
@@ -294,6 +294,18 @@ grpcsharp_batch_context_server_rpc_new_method(
   return ctx->server_rpc_new.call_details.method;
 }
 
+GPR_EXPORT const char *GPR_CALLTYPE
+grpcsharp_batch_context_server_rpc_new_host(
+    const grpcsharp_batch_context *ctx) {
+  return ctx->server_rpc_new.call_details.host;
+}
+
+GPR_EXPORT gpr_timespec GPR_CALLTYPE
+grpcsharp_batch_context_server_rpc_new_deadline(
+    const grpcsharp_batch_context *ctx) {
+  return ctx->server_rpc_new.call_details.deadline;
+}
+
 GPR_EXPORT const grpc_metadata_array *GPR_CALLTYPE
 grpcsharp_batch_context_server_rpc_new_request_metadata(
     const grpcsharp_batch_context *ctx) {