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