Ensure that HttpConfiguration.EnsureInitialized() - c#

I've installed Visual Studio 2013 and when I run my app I get the error below.
I've got no idea as to where I'm to initialized this object.
What to do?
Server Error in '/' Application.
The object has not yet been initialized. Ensure that HttpConfiguration.EnsureInitialized() is called in the application's startup code after all other initialization code.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.InvalidOperationException: The object has not yet been initialized. Ensure that HttpConfiguration.EnsureInitialized() is called in the application's startup code after all other initialization code.
Source Error:
An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.
Stack Trace:
[InvalidOperationException: The object has not yet been initialized. Ensure that HttpConfiguration.EnsureInitialized() is called in the application's startup code after all other initialization code.]
System.Web.Http.Routing.RouteCollectionRoute.get_SubRoutes() +101
System.Web.Http.Routing.RouteCollectionRoute.GetRouteData(String virtualPathRoot, HttpRequestMessage request) +63
System.Web.Http.WebHost.Routing.HttpWebRoute.GetRouteData(HttpContextBase httpContext) +107
System.Web.Routing.RouteCollection.GetRouteData(HttpContextBase httpContext) +233
System.Web.Routing.UrlRoutingModule.PostResolveRequestCache(HttpContextBase context) +60
System.Web.Routing.UrlRoutingModule.OnApplicationPostResolveRequestCache(Object sender, EventArgs e) +82
System.Web.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +136
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +69
Version Information: Microsoft .NET Framework Version:4.0.30319; ASP.NET Version:4.0.30319.18408
This is for AlumCloud

If you do it at the end of Application_Start it will be too late, as WebApiConfig.Register has been called.
The best way to resolve this is to use new initialization method by replacing in Global.asax :
WebApiConfig.Register(GlobalConfiguration.Configuration);
by
GlobalConfiguration.Configure(WebApiConfig.Register);

See #gentiane's answer below for the correct way to handle this now.
At the end of the Application_Start method in Global.Asax.cs try adding:-
GlobalConfiguration.Configuration.EnsureInitialized();

I actually got this error when I was using Attribute Routing within my WebApi.
I had
[Route("webapi/siteTypes/{siteTypeId"]
instead of
[Route("webapi/siteTypes/{siteTypeId}"]
for my route and got this error. I had simply missed out the closing curly bracket. Once I added it back in, this error didn't occur again.

This is old, but is the first result on google when searching for this error. After quite a bit of digging I was able to figure out what was going on.
tldr:
All GlobalConfiguration.Configure does is invoke your action and call EnsureInitialized(). config.MapAttributeRoutes() must be called before EnsureInitialized() since EnsureInitialized only runs once.
Meaning: if you're coming from an existing Mvc project, all you have to do is:
Add
GlobalConfiguration.Configuration.EnsureInitialized();
to the bottom of your Application_Start method.
OR
Move your entire configuration into a single call to GlobalConfiguration.Configure:
GlobalConfiguration.Configure(config =>
{
WebApiConfig.Register(config);
config.MapAttributeRoutes();
...
});
Digging Deeper
HttpConfiguration.Configuration has an "Initializer" property defined like this:
public Action<HttpConfiguration> Initializer;
HttpConfiguration.EnsureInitialized() runs this action and sets _initialized to true
public void EnsureInitialized()
{
if (_initialized)
{
return;
}
_initialized = true;
Initializer(this);
}
HttpConfiguration.MapAttributeRoutes calls internal method AttributeRoutingMapper.MapAttributeRoutes which sets HttpConfiguration.Initializer
public static void MapAttributeRoutes(...)
{
RouteCollectionRoute aggregateRoute = new RouteCollectionRoute();
configuration.Routes.Add(AttributeRouteName, aggregateRoute);
...
Action<HttpConfiguration> previousInitializer = configuration.Initializer;
configuration.Initializer = config =>
{
previousInitializer(config);
...
};
}
GlobalConfiguration.Configure runs EnsureInitialized immediately after invoking your action:
public static void Configure(Action<HttpConfiguration> configurationCallback)
{
if (configurationCallback == null)
{
throw new ArgumentNullException("configurationCallback");
}
configurationCallback.Invoke(Configuration);
Configuration.EnsureInitialized();
}
Don't forget, if you run in to a wall, the source for asp.net is available at http://aspnetwebstack.codeplex.com/SourceControl/latest

I've had a related issue. Sometimes calling GlobalConfiguration.Configure multiple times triggers this error. As a workaround, I've put all configuration initialization logic in one place.

IF THIS ERROR SEEMS TO HAVE COME "OUT OF NOWHERE", i.e. your app was working perfectly fine for a while, ask yourself: Did I add an action to a controller or change any routes prior to seeing this error?
If the answer is yes (and it probably is), you likely made a mistake in the process. Incorrect formatting, copy/pasting an action and forgetting to make sure the endpoint names are unique, etc. will all end you up here. The suggestion that this error makes on how to resolve it can send you barking up the wrong tree.

For me, the problem was that I was trying to use named parameters for query string fields in my routes:
[Route("my-route?field={field}")]
public void MyRoute([FromUri] string field)
{
}
Query string fields are automatically mapped to parameters and aren't actually part of the route definition. This works:
[Route("my-route")]
public void MyRoute([FromUri] string field)
{
}

Although the above answer works if incase that is not set, In my case this stuff was set already. What was different was that, for one of the APIs I had written, I had prefixed the route with a / . Example
[Route("/api/abc/{client}")]
.Changing this to
[Route("api/abc/{client}")]
fixed it for me

Call
GlobalConfiguration.Configuration.MapHttpAttributeRoutes();
before
GlobalConfiguration.Configure(c => ...);
completes its execution.

I got this error when the version of Newtonsoft.Json was different in my main project compared to the helper project

One typically gets this exception when route templates in "Attribute Routing" are not proper.
For example, i got this when i wrote the following code:
[Route("{dirName:string}/contents")] //incorrect
public HttpResponseMessage GetDirContents(string dirName) { ... }
In route constraints syntax {parameter:constraint}, constraint by default is of type string. No need to mention it explicitly.
[Route("{dirName}/contents")] //correct
public HttpResponseMessage GetDirContents(string dirName) { ... }

I began getting this error one day. After I'd altered our app to call EnsureInitialized() I was able to see the root cause.
I had a custom attribute, a filter, on an action. That attribute class had had a breaking change made in the NuGet package in which it lives.
Even though I'd updated the the code and it all compiled, the local IIS worker was loading an old DLL and not finding a class member during initialization, reading attributes on actions etc.
For some reason (possibly due to order/when our logging is initialized), this error was not discoverable, possibly leaving the WebAPI in a strange state, until I'd added EnsureInitialized() which caught the exception and surfaced it.
Performing a proper bin and obj clean via a handy script resolved it.

In my case I created the webservice in project A and started it from Project B and I got exactly this error. The problem was that some .dll-files which are required by A where missing in the build-output-folder of B. Ensure that these .dll-files are available fixed it.

In my case , i used an Entity as parameter of my action that its 'Schema' is missing.
Wrong attribute:
[Table("Table name", Schema = "")]
Correct :
[Table("Table name", Schema = "schema name")]

In my case I fixed replacing:
<Route("{id:string}")>
with
<Route("{id}")>
Strange that I was sure that the original code was working before suddenly stopping, go figure....

I experienced this similar error.
<Error>
<Message>An error has occurred.</Message>
<ExceptionMessage>The object has not yet been initialized. Ensure that HttpConfiguration.EnsureInitialized() is called in the application's startup code after all other initialization code.</ExceptionMessage>
<ExceptionType>System.InvalidOperationException</ExceptionType>
<StackTrace> at System.Web.Http.Routing.RouteCollectionRoute.get_SubRoutes() at System.Web.Http.Routing.RouteCollectionRoute.GetRouteData(String virtualPathRoot, HttpRequestMessage request) at System.Web.Http.WebHost.Routing.HttpWebRoute.GetRouteData(HttpContextBase httpContext)</StackTrace>
</Error>
After fiddling with it for a while, I realized two problems: directory name collides with routing prefix and routing prefix must not end with '/'. When starting up the service for debugging I got this browser error after adding the SampleController.cs.
The folder structure
/api/Controllers/SampleController.cs
/api/Model/...
SampleController.cs
[RoutePrefix("api/sub/{parameterId}/more/")]
public class SampleController : ApiController
{
[HttpGet]
[Route("")]
public IHttpActionResult Get(int parameterId)
{
return Ok("Knock Knock...");
}
}
Changing the routing prefix to not end in '/' and not colliding with the directory name solved the problem.

Related

How to debug into attribute code that is from nuget?

Setup
I have a method with attribute on it that I created. I have packed the attribute into a nuget package (debug symbol mode) like I do when I want to debug into nuget packages.
Question
How can I step into this attribute? Do I need to put some other "step into this" attribute into my attribute code? I have only found the attribute that stops my from debugging DebuggerStepThroughAttribute but nothing that will allow me to explicitly stop when in debug (witch you of course don´t need normally).
I hope I have explained this well enough.
Edit (more info)
Jordan suggested calling GetCustomAttributes in the method but that is not an option (at the least in my case). My attribute is doing a token validation on the API call so you are not allowed (401) into the method if the code in the attribute denies it access. And also I can´t put a brake point into the nuget packgage, I need to be able to step into that code.
Edit 2 (finally... code)
So finally there is code.. I did´t think I needed one but here we are :-).
I have implemented my own attribute (as you can do) where there is code I would love to be able to debug into.
public class TokenAuthenticate : ActionFilterAttribute, IAuthenticationFilter
{
public override void OnActionExecuting(HttpActionContext actionContext)
{
base.OnActionExecuting(actionContext);
}
public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
{
base.OnActionExecuted(actionExecutedContext);
}
public bool AllowMultiple => true;
public async Task AuthenticateAsync(HttpAuthenticationContext context, CancellationToken cancellationToken)
{
//... where I want to debug into
}
}
This attribute then just goes on the method or class like this [TokenAuthenticate ]
According to MSDN, Attributes are instantiated lazily:
It's important to note that these Attribute objects are instantiated
lazily. That is, they won't be instantiated until you use
GetCustomAttribute or GetCustomAttributes. They are also instantiated
each time. Calling GetCustomAttributes twice in a row will return two
different instances of ObsoleteAttribute.
If you need to step into them you should be able to do this by calling GetCustomAttributes on the Type in question and placing a break point inside the Attribute.
In my case I had to debug a custom attribute that I created. I came to an peculiar solution, but it worked for me.
You can add a constructor to your TokenAuthenticate class and invoke it from your Startup.cs for example, if you are working with WebApi.
public void Configure(...)
{
#if DEBUG
// Hack to debug your custom attribute, put a breakpoint here
var myVar = new TokenAuthenticate ();
#endif
Then you can step into the constructor when your web project is starting... and when the code of your TokenAuthenticate class appears, you can put a breakpoint where you want it the debugger to stop in future.
In case you have your custom attribute in your own nuget package. you can include the PDB file into your generated nuget package, with this settings at the *.csproj file used to generate de nupkg.
<IncludeSymbols>true</IncludeSymbols>
I hope this works for you and purity detractors not to be angry with me.
Reference: Including pdb files into nupkg

MVC and OData, side by side

We've got a set of MVC apis already in place, but I've been asked to put up OData versions. I'm trying to co-locate both sets in the same application to share things like custom role providers. I'm new to OData and so far MVC lessons don't seem to translate directly.
With MVC, we took the generic initialization and managed all the routes with RouteAttribute and I tried to go the same style using ODataRouteAttribute, but all my odata paths come up 404 and the $metadata query returns a 500 saying the configuration hasn't been initialized.
Here's the app start configuration chunk (ODataApiConfig added after the MVC one):
AreaRegistration.RegisterAllAreas();
GlobalConfiguration.Configure(WebApiConfig.Register);
ODataApiConfig.Configure(GlobalConfiguration.Configuration);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
GlobalConfiguration.Configuration.EnsureInitialized();
And here's what's in ODataApiConfig:
// OData v7 replacement for configuration.EnableCaseInsensitive(true);
configuration.MapODataServiceRoute("odata", "odata",
builder =>
builder.AddService<IEnumerable<IODataRoutingConvention>>(ServiceLifetime.Singleton, sp => ODataRoutingConventions.CreateDefaultWithAttributeRouting("odata", configuration))
.AddService<ODataUriResolver>(ServiceLifetime.Singleton, sp => new CaseInsensitiveResolver())
);
ODataModelBuilder modeler = new ODataConventionModelBuilder();
modeler.EntitySet<Task>("Tasks");
configuration.MapODataServiceRoute(
routeName: "ODataRoute",
routePrefix: "odata",
model: modeler.GetEdmModel()
);
configuration.EnsureInitialized();
And here's an example of an api I'm trying to hook up (to get a list of tasks assigned to an employee):
[HttpGet]
[EnableQuery]
[ODataRoute("v0.1/employee/{userGuid}/tasks")]
[ODataAuthorize(Roles = "Assignee")]
public IHttpActionResult GetMyTasks([FromODataUri]string userGuid)
{
...
}
So I'm puzzled why
a) A call to ~/odata/$metadata throws a "The object has not yet been initialized. Ensure that HttpConfiguration.EnsureInitialized() is called in the application's startup code after all other initialization code." I tried calling EnsureInitialized() at the end of both the OData/MVC initialization and inside the OData initialize routine and it still throws the same error.
b) My ~/odata/employees/{userGuid}/tasks path comes up 404.
Any pointers will be appreciated.
Thanks
EDIT: It appears that the ~/odata/$metadata exception is related to the use of [ODataRoute] attributes. That seems to be enabled by default (and causing the exception); when I tried explicitly creating a routing convention object and DI-ing it, the $metadata exception went away. Didn't produce much useful, but the exception went away.
The stack trace on the exception is below; I tried breaking on any InvalidOperationExceptions thrown but did not get a break in the debugger
{"Message":"An error has occurred.","ExceptionMessage":"The object has not yet been initialized. Ensure that HttpConfiguration.EnsureInitialized() is called in the application's startup code after all other initialization code.","ExceptionType":"System.InvalidOperationException","StackTrace":" at System.Web.OData.Routing.Conventions.AttributeRoutingConvention.get_AttributeMappings()
at System.Web.OData.Routing.Conventions.AttributeRoutingConvention.SelectController(ODataPath odataPath, HttpRequestMessage request)
at System.Web.OData.Routing.ODataPathRouteConstraint.SelectControllerName(ODataPath path, HttpRequestMessage request)
at System.Web.OData.Routing.ODataPathRouteConstraint.Match(HttpRequestMessage request, IHttpRoute route, String parameterName, IDictionary`2 values, HttpRouteDirection routeDirection)
at System.Web.Http.Routing.HttpRoute.ProcessConstraint(HttpRequestMessage request, Object constraint, String parameterName, HttpRouteValueDictionary values, HttpRouteDirection routeDirection)
at System.Web.Http.Routing.HttpRoute.ProcessConstraints(HttpRequestMessage request, HttpRouteValueDictionary values, HttpRouteDirection routeDirection)\r\n at System.Web.Http.Routing.HttpRoute.GetRouteData(String virtualPathRoot, HttpRequestMessage request)
at System.Web.Http.WebHost.Routing.HttpWebRoute.GetRouteData(HttpContextBase httpContext)"}
EDIT: At least I've got an answer on the $metadata call.
My initialization sequence had been informed by this article : https://blogs.msdn.microsoft.com/davidhardin/2014/12/17/web-api-odata-v4-lessons-learned/
which said that you had to initialize the Web Api calls first. I found the opposite. The above exception came as a result of initializing Web Api first. When I flipped them, the $metadata call started returning my Task entity set.
Unfortunately, my [ODataRoute] declarations in my TasksController still aren't getting routed.
Okay, the issue seems to be that some of the advice in here is out-dated:
https://blogs.msdn.microsoft.com/davidhardin/2014/12/17/web-api-odata-v4-lessons-learned/
Specifically, the $metadata exception turned out to be caused by setting up OData after Web API (per the above article). You have to initialize OData before Web Api.
Second, the point about controllers finding differentiation with the route prefix is wrong. I did segregate my web api controllers and odata controllers in different directories and I did use RoutePrefix/ODataRoutePrefix to put them on different paths.
But after getting the source code for AttributeRoutingConvention from github and using that for debugging, I found the following:
If you have 2 controllers with the same class name (e.g. both are called TaskController), even though they have different prefix paths and live in different directories, they collide. Both get dropped silently from the processing, so they are not found when a request comes in. Hence the 404.
So regardless of the prefixes and route attributes, the classes need to be named differently to be included.

Instantiation of a controller in OnActionExecuting (...not throwing a 404) in MVC Azure

The objective is to add a maintenance batch on the same url of the administration of an Azure MVC site. The url should be something like:
https://admin.mysite.com/Batch?pass=HKE671
I decided to override OnActionExecuting and to capture the information I need in the url to trigger the maintenance method. I am not familiar with MVC projects, and this may not sound very conventional...
protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
EmailUtility.SendSupportEmail("DEBUG - On result executing", ""); //I receive this email
int y = 14;
if (Request.Url.Query.Length > y)
{
string url = Request.Url.Query.Remove(0, y); // I remove ?ReturnUrl=%2f
if (url.StartsWith("Batch"))
{
mySite.Admin.Web.Controllers.TenantController controller = new mySite.Admin.Web.Controllers.TenantController();
EmailUtility.SendSupportEmail("DEBUG - starts maintenance", ""); // I don't receive this one
controller.maintenance(HttpUtility.ParseQueryString(url).Get("pass"));
};
}
base.OnActionExecuting(filterContext);
}
This code works as well as I need on local, the maintenance method is called and does the job. But when deployed on Azure, this modification throws a 404 error. Interestingly, I send two debug emails : I don’t receive the second one "DEBUG - starts maintenance", therefore my 404 error comes from the instantiation of a controller in OnActionExecuting.
First, I would like to understand why is the behavior different between my development machine and Azure?
Then, how can I make it work? Thanks,
EDITED on Jan 4:
I made a little progress, but this issue is still unsolved.
- About the difference between my dev machine and Azure: there are a few redirections on this site: https, 404 and non-existent domain. I assumed it was due to a 404 error. Encapsulating the code with a try/catch didn't sent me any error, so I am guessing that I can suppress the 404 from the hypothesis.
- I tried the code above on OnAuthorization without having more success.
- I noticed that the first email DEBUG - On result executing is in fact sent at the first test only. It is not sent the second time I run my test. This doesn't make any sense to me, because the session should be checked every time.
Conclusion for today: it seems to be more a routing/redirection problem.
Why don't you do:
protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
try {
//your code here
} catch (Exception ex){
EmailUtility.SendSupportEmail("Execution failed: " + ex.Message , "");
}
}
If your code is throwing an exception, this should give you a better understanding on why it is failing.
But more important, a more robust way of checking for the correct URL would be:
if (filterContext.HttpContext.Request.Url.AbsolutePath.EndsWith("Batch")){
}
As far as i can tell your string variable "url" will not ever start with "Batch", because Request.Url.Query only conains the part after the "?" thus making your check always return false. Why this IS working on localhost is hard to tell, but in my opinion it shouldn't.
Actually, to work in all cases your check should be:
if (filterContext.HttpContext.Request.Url.AbsolutePath.ToLower().EndsWith("batch") || filterContext.HttpContext.Request.Url.AbsolutePath.ToLower().EndsWith("batch/")){
}
After your edit:
Ok, so what's happening is that you're requesting the action "Batch" in Home Controller, but because you're not authenticated you are redirected to LogOn in Account Controller. You should be seeing a login page, unless there's no associated LogOn view in your Views folder, or no AccountController at all, in both cases an exception is thrown.
Is the Batch method supposed to check for authentication? If not, remove the [Authorize] annotation from this method in HomeController and you should be fine.
You still have to adjust the if-check though, because it actually only evaluates to true on the LogOn page, and false if you actually get to the Batch page.
Shame on me, the problem was somewhere else!... The code above works well, but the routing of this site rejected an incomplete url. In this case, it had to contain the project name: https://admin.mysite.com/Admin/Batch?pass=HKE671 Then all is back to normal!
So the answer is: the behavior is different on my local computer because the local host of my development machine doesn't route projects of the solution the same way Azure does.
Many thanks for your help!

URL rewrite in OWIN middleware

I have a problem with URL rewriting which works in Global.asax but not in OWIN middleware.
Global.asax code
protected void Application_BeginRequest()
{
//Perfectly working rewrite.
//By route rules, this resolves to the action Global()
//of the HomeController
HttpContext.Current.RewritePath("Home/Global");
}
OWIN middleware code (used for culture detection, code shortened for brevity)
public class GlobalizationMiddleware : OwinMiddleware
{
public GlobalizationMiddleware(OwinMiddleware next)
: base(next)
{ }
public async override Task Invoke(IOwinContext context)
{
context.Request.Path = new PathString("/Home/Global");
await Next.Invoke(context);
}
}
I expect that "Global" action of the controller "Home" gets called...but instead, the default action "Index" is called.
After the Path is changed context.Request.Uri.AbsoluteUri is http://localhost/Global/Home
But Controller's Request.Url.AbsoluteUri is still http://localhost
I even tried context.Environment["owin.RequestPath"] = "/Home/Global"; but that doesn's seem to work either.
Before anyone asks, yes, I call the IAppBuilder.Use(typeof(GlobalizationMiddleware)) in Startup.cs and the debugger enters the Invoke method.
What am I doing wrong?
EDIT
I even tried referencing System.Web and then doing this...doesn't work either :(
System.Web.Routing.RequestContext requestContext = context.Environment["System.Web.Routing.RequestContext"] as System.Web.Routing.RequestContext;
requestContext.HttpContext.RewritePath("/Home/Global");
System.Web.HttpContextBase contextBase = context.Environment["System.Web.HttpContextBase"] as System.Web.HttpContextBase;
contextBase.RewritePath("/Home/Global");
EDIT 2 - Found a working solution (see below) but I'm unsure whether it's the right solution, comments would be appreciated :)
I found a working solution.
Unfortunately, I needed to include System.Web. I'm directly altering the RouteData object in the RequestContext.
System.Web.Routing.RequestContext requestContext = context.Environment["System.Web.Routing.RequestContext"] as System.Web.Routing.RequestContext;
requestContext.HttpContext.RewritePath("Home/Global");
requestContext.RouteData.Values["action"] = "Global";
But this feels too hacky to my tastes... I'm not sure if this is the right solution so I won't accept this as the valid answer, maybe someone will come with a better solution.
I ran into this as well, and found that one way to get this working is just to use HttpContext
HttpContext.Current.RewritePath("/new/path");
If you're already including System.Web anyway this seems to be a workable solution.
OWIN is a layer on top of ASP.NET (System.Web), and some of the ASP.NET components (such as MVC) are not built on top of OWIN but actually ASP.NET directly.
Looking deeper, OwinRequest doesn't have any reference to System.Web.HttpContext and instead just deals with Environment (source), so that's why setting the OWIN request path doesn't affect ASP.NET apps.

Can't Mock interface method when parameter is MultipartFormDataStreamProvider

I have this weird problem when trying to mock an interface with MockedClass.Setup(x => x.Method()).
This is the interface I'm mocking.
public interface IClassFactory
{
object GetValueFromFormData(string key, MultipartFormDataStreamProvider provider);
}
This is my test.
[TestMethod]
[ExpectedException(typeof(NullReferenceException))]
public async Task ClassApiController_ImportClassList_ThrowsNullReferenceExceptionWhenNoClassId()
{
// Arrange
_classFactory = new Mock<IClassFactory>();
// THIS IS THE LINE THAT GIVES AN EXCEPTION
_classFactory.Setup(x => x.GetValueFromFormData("classIdNull", null)).Returns(string.Empty);
ClassApiController controller = new ClassApiController(_classRepository.Object, _surveyRepository.Object, _classFactory.Object);
// Act
string result = await controller.ImportClassList();
}
If you look at my comment "THIS IS THE LINE THAT GIVES AN EXCEPTION" you see I send null, but it doesn't matter if I send the MultipartFormDataStreamProvider as an instansiated class instead, I still get the same exception.
Exception message: System.ArgumentException: Expression of type 'System.Net.Http.MultipartFormDataStreamProvider' cannot be used for parameter of type 'System.Net.Http.MultipartFormDataStreamProvider' of method 'System.Object GetValueFromFormData(System.String, System.Net.Http.MultipartFormDataStreamProvider)'
If you know why I can't mock the method just because it has this object as parameter, please help me, I'm clueless.
Thanks!
EDIT:
See solution in my answer
you should try
_classFactory = Mock.Of<IClassFactory>();
Mock.Get(_classFactory).Setup(x => x.GetValueFromFormData("classIdNull", It.IsAny<MultipartStreamProvider>()))
.Returns(string.Empty);
With the help of #Vignesh.N I finally solved it. The simple answer in this case was that my solution is divided into several projects. Web, Test, Data and so on. In the web project I had referenced the web api .dll:s via Nuget and in the test project I had referenced them directly via Add references -> Assemblies -> Framework. Thereby the .dll:s had identical Versions but not File versions. After making Nuget take care of all the projects web api .dll files it worked instantly.
So all in all, stupid mistake and hard to spot.

Categories

Resources