mirror of https://github.com/dapr/dotnet-sdk.git
				
				
				
			- Added null-conditional operator to StateEntryApplicationModelProvider.OnProvidersExecuted when checking BindingSource to prevent startup null reference exceptions in certain implementations. (#765)
- Added null check and throws unit tests for StateEntryApplicationModelProvider
This commit is contained in:
		
							parent
							
								
									75bdb8ce2f
								
							
						
					
					
						commit
						fc54f21d00
					
				|  | @ -28,7 +28,7 @@ namespace Dapr.AspNetCore | ||||||
|                     { |                     { | ||||||
|                         // Not bindable. |                         // Not bindable. | ||||||
|                     } |                     } | ||||||
|                     else if (property.BindingInfo.BindingSource.Id == "state") |                     else if (property.BindingInfo.BindingSource?.Id == "state") | ||||||
|                     { |                     { | ||||||
|                         // Already configured, don't overwrite in case the user customized it. |                         // Already configured, don't overwrite in case the user customized it. | ||||||
|                     } |                     } | ||||||
|  | @ -46,7 +46,7 @@ namespace Dapr.AspNetCore | ||||||
|                         { |                         { | ||||||
|                             // Not bindable. |                             // Not bindable. | ||||||
|                         } |                         } | ||||||
|                         else if (parameter.BindingInfo.BindingSource.Id == "state") |                         else if (parameter.BindingInfo.BindingSource?.Id == "state") | ||||||
|                         { |                         { | ||||||
|                             // Already configured, don't overwrite in case the user customized it. |                             // Already configured, don't overwrite in case the user customized it. | ||||||
|                         } |                         } | ||||||
|  |  | ||||||
|  | @ -0,0 +1,94 @@ | ||||||
|  | // ------------------------------------------------------------ | ||||||
|  | // Copyright (c) Microsoft Corporation. | ||||||
|  | // Licensed under the MIT License. | ||||||
|  | // ------------------------------------------------------------ | ||||||
|  | 
 | ||||||
|  | namespace Dapr.AspNetCore.Test | ||||||
|  | { | ||||||
|  |     using System; | ||||||
|  |     using System.Collections.Generic; | ||||||
|  |     using System.Linq; | ||||||
|  |     using System.Reflection; | ||||||
|  |     using System.Text.Json; | ||||||
|  |     using System.Threading.Tasks; | ||||||
|  |     using Dapr.AspNetCore.Resources; | ||||||
|  |     using Dapr.Client; | ||||||
|  |     using Dapr.Client.Autogen.Grpc.v1; | ||||||
|  |     using FluentAssertions; | ||||||
|  |     using Microsoft.AspNetCore.Http; | ||||||
|  |     using Microsoft.AspNetCore.Mvc; | ||||||
|  |     using Microsoft.AspNetCore.Mvc.ApplicationModels; | ||||||
|  |     using Microsoft.AspNetCore.Mvc.ModelBinding; | ||||||
|  |     using Microsoft.AspNetCore.Mvc.ModelBinding.Validation; | ||||||
|  |     using Microsoft.AspNetCore.Mvc.Routing; | ||||||
|  |     using Microsoft.Extensions.DependencyInjection; | ||||||
|  |     using Xunit; | ||||||
|  | 
 | ||||||
|  |     public class StateEntryApplicationModelProviderTest | ||||||
|  |     { | ||||||
|  |         [Fact] | ||||||
|  |         public void OnProvidersExecuted_NullActionsBindingSource() | ||||||
|  |         { | ||||||
|  |             var provider = new StateEntryApplicationModelProvider(); | ||||||
|  |             var context = CreateContext(nameof(ApplicationModelProviderTestController.Get)); | ||||||
|  | 
 | ||||||
|  |             Action action = () => provider.OnProvidersExecuted(context); | ||||||
|  | 
 | ||||||
|  |             action | ||||||
|  |                 .Should() | ||||||
|  |                 .NotThrow<NullReferenceException>(); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         [Fact] | ||||||
|  |         public void OnProvidersExecuted_StateEntryParameterThrows() | ||||||
|  |         { | ||||||
|  |             var provider = new StateEntryApplicationModelProvider(); | ||||||
|  |             var context = CreateContext(nameof(ApplicationModelProviderTestController.Post)); | ||||||
|  | 
 | ||||||
|  |             Action action = () => provider.OnProvidersExecuted(context); | ||||||
|  | 
 | ||||||
|  |             action | ||||||
|  |                 .Should() | ||||||
|  |                 .Throw<InvalidOperationException>(SR.ErrorStateStoreNameNotProvidedForStateEntry); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         private ApplicationModelProviderContext CreateContext(string methodName) | ||||||
|  |         { | ||||||
|  |             var controllerType = typeof(ApplicationModelProviderTestController).GetTypeInfo(); | ||||||
|  |             var typeInfoList = new List<TypeInfo> { controllerType }; | ||||||
|  | 
 | ||||||
|  |             var context = new ApplicationModelProviderContext(typeInfoList); | ||||||
|  |             var controllerModel = new ControllerModel(controllerType, new List<object>(0)); | ||||||
|  | 
 | ||||||
|  |             context.Result.Controllers.Add(controllerModel); | ||||||
|  | 
 | ||||||
|  |             var methodInfo = controllerType.AsType().GetMethods().First(m => m.Name.Equals(methodName)); | ||||||
|  |             var actionModel = new ActionModel(methodInfo, controllerModel.Attributes) | ||||||
|  |             { | ||||||
|  |                 Controller = controllerModel | ||||||
|  |             }; | ||||||
|  | 
 | ||||||
|  |             controllerModel.Actions.Add(actionModel); | ||||||
|  |             var parameterInfo = actionModel.ActionMethod.GetParameters().First(); | ||||||
|  |             var parameterModel = new ParameterModel(parameterInfo, controllerModel.Attributes) | ||||||
|  |             { | ||||||
|  |                 BindingInfo = new BindingInfo(), | ||||||
|  |                 Action = actionModel, | ||||||
|  |             }; | ||||||
|  | 
 | ||||||
|  |             actionModel.Parameters.Add(parameterModel); | ||||||
|  | 
 | ||||||
|  |             return context; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         [Controller] | ||||||
|  |         private class ApplicationModelProviderTestController : Controller | ||||||
|  |         { | ||||||
|  |             [HttpGet] | ||||||
|  |             public void Get([Bind(Prefix = "s")]int someId) { } | ||||||
|  | 
 | ||||||
|  |             [HttpPost] | ||||||
|  |             public void Post(StateEntry<Subscription> bogusEntry) { } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
		Loading…
	
		Reference in New Issue