Problem
There's WCF connected to Silverlight. When it's time for the service to return args, it returns an error with the exception and no actual result that it should return.
Exception
Value cannot be null.
Parameter name: headers
There's no parameter named headers. I put emphasis on not having a field named headers in the model which the service returns.
Possible Solution which didn't work out
Checked every Any(), Where and Count() not used when it's null
Checked {get;} doesn't exist except when it's with set;
Traced whole of code and it didn't have any exception or null value
Checked whole of code to be in different try-catches
Checked Web.config and all of connection strings are right; .
I updated the service multiple times and checked its configuration
I couldn't remove defining query I wasn't allowed to
Stack Trace
at System.ServiceModel.AsyncResult.End[TAsyncResult](IAsyncResult result)
at System.ServiceModel.Channels.ServiceChannel.EndCall(String action, Object[] outs, IAsyncResult result)
at System.ServiceModel.ClientBase`1.ChannelBase`1.EndInvoke(String methodName, Object[] args, IAsyncResult result)
at UIE.SrvE.SrvEClient.SrvEClientChannel.EndGetSubmit(IAsyncResult result)
at UIE.SrvE.SrvEClient.UIE.SrvEngineer.ISrvE.EndGetSubmit(IAsyncResult result)
at UIE.SrvE.SrvEClient.OnEndGetSubmit(IAsyncResult result)
at System.ServiceModel.ClientBase`1.OnAsyncCallCompleted(IAsyncResult result)
There are so many questions about this exception like this one source but none of them is about headers.
Please, suggest to me any possible solutions.
Related
In the project I am involved with now, we are using dotnet-nswag.dll to generate a typescript api client. I am now trying to switch from using local secrets to secrets stored in azure key vault (I hope to simplify new developers' entry to the project). I however bumped into a problem, that when I use something like below:
builder.ConfigureAppConfiguration((ctx, cfg) =>
{
if (ctx.HostingEnvironment.IsDevelopment())
{
var keyVaultEndpoint = new Uri(Environment.GetEnvironmentVariable("DevEnv_KVUri"));
cfg.AddAzureKeyVault(keyVaultEndpoint, new DefaultAzureCredential());
}
});
I no longer can generate the nswag typescript api client. My investigation led me to the discovery that nswag fails becasue DevEnd_KVUri does not exists at the generation time. I have this env var added in my launchSettigns.json and it is available when I test my app. However, I would like to instruct nswag not to try to include whatever is triggering it to also go through that key vault endpoint.
If I hard-code the url (and it is a KeyVault url that I have access to), then the generation passes. Generated client does not have any endpoints pointing to my hard-coded url. However I do not like the solution, where I have to hard-code (not even fake but a working one) my key vault address.
Unfortunately, I did not find any solution to my problem.
Edit 1:
The command that executes generation:
dotnet "C:\Users\myname\.nuget\packages\nswag.msbuild\13.16.0\build\../tools/Net50/dotnet-nswag.dll" run nswag.json /variables:Configuration=Debug`
The exception thrown by the generator when no url is provided
System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation.
---> System.ArgumentNullException: Value cannot be null. (Parameter 'uriString')
at System.Uri..ctor(String uriString)
at Lib.KeyVault.Extensions.IWebHostBuilderExtensions.<>c.<UseKeyVault>b__0_1(HostBuilderContext ctx, IConfigurationBuilder bld) in C:\dotnet\net\lib\Lib.KeyVault.Extensions\IWebHostBuilderExtensions.cs:line 50
at Microsoft.Extensions.Hosting.HostBuilder.BuildAppConfiguration()
at Microsoft.Extensions.Hosting.HostBuilder.Build()
at NSwag.Commands.ServiceProviderResolver.GetServiceProvider(Assembly assembly) in /_/src/NSwag.Commands/HostApplication.cs:line 61
at NSwag.Commands.Generation.AspNetCore.AspNetCoreToOpenApiGeneratorCommandEntryPoint.Process(String commandContent, String outputFile, String applicationName) in /_/src/NSwag.Commands/Commands/Generation/AspNetCore/AspNetCoreToOpenApiGeneratorCommandEntryPoint.cs:line 27
--- End of inner exception stack trace ---
at System.RuntimeMethodHandle.InvokeMethod(Object target, Span`1& arguments, Signature sig, Boolean constructor, Boolean wrapExceptions)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters)
at NSwag.AspNetCore.Launcher.Program.Main(String[] args) in /_/src/NSwag.AspNetCore.Launcher/Program.cs:line 132
System.InvalidOperationException: Swagger generation failed with non-zero exit code '1'.
at NSwag.Commands.Generation.AspNetCore.AspNetCoreToSwaggerCommand.RunAsync(CommandLineProcessor processor, IConsoleHost host) in /_/src/NSwag.Commands/Commands/Generation/AspNetCore/AspNetCoreToOpenApiCommand.cs:line 231
at NSwag.Commands.NSwagDocumentBase.GenerateSwaggerDocumentAsync() in /_/src/NSwag.Commands/NSwagDocumentBase.cs:line 275
at NSwag.Commands.NSwagDocument.ExecuteAsync() in /_/src/NSwag.Commands/NSwagDocument.cs:line 81
at NSwag.Commands.Document.ExecuteDocumentCommand.ExecuteDocumentAsync(IConsoleHost host, String filePath) in /_/src/NSwag.Commands/Commands/Document/ExecuteDocumentCommand.cs:line 85
at NSwag.Commands.Document.ExecuteDocumentCommand.RunAsync(CommandLineProcessor processor, IConsoleHost host) in /_/src/NSwag.Commands/Commands/Document/ExecuteDocumentCommand.cs:line 32
at NConsole.CommandLineProcessor.ProcessSingleAsync(String[] args, Object input)
at NConsole.CommandLineProcessor.ProcessAsync(String[] args, Object input)
at NSwag.Commands.NSwagCommandProcessor.ProcessAsync(String[] args) in /_/src/NSwag.Commands/NSwagCommandProcessor.cs:line 61
I've implemented a WCF duplex service IMyDuplexService with a callback contract IMyCallbackContract.
It was deployed successfully; clients can subscribe to the service and the service can call methods on the client using the callback channel without issues.
I've since added a new method to the callback contract and it can also be deployed successfully; old clients can still subscribe to the service as well as new clients, the service can call the old methods on both the old and new clients using the callback channel, as well as new methods on the new clients without issues.
Is there any way to determine if a specific client is an old or new client without having to implement this "versioning" logic myself?
For example, if the client was implemented using the older version of the callback contract and the service tries to call the new method on the old client, the following exception is thrown:
System.ServiceModel.ActionNotSupportedException occurred
HResult=-2146233087
Message=The message with Action 'http://domain/virtual_directory/IMyDuplexService/MyNewMethod' cannot be processed at the receiver, due to a ContractFilter mismatch at the EndpointDispatcher. This may be because of either a contract mismatch (mismatched Actions between sender and receiver) or a binding/security mismatch between the sender and the receiver. Check that sender and receiver have the same contract and the same binding (including security requirements, e.g. Message, Transport, None).
Source=mscorlib
StackTrace:
Server stack trace:
at System.ServiceModel.Channels.ServiceChannel.ThrowIfFaultUnderstood(Message reply, MessageFault fault, String action, MessageVersion version, FaultConverter faultConverter)
at System.ServiceModel.Channels.ServiceChannel.HandleReply(ProxyOperationRuntime operation, ProxyRpc& rpc)
at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)
Exception rethrown at [0]:
at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
at MyService.IMyCallbackContract.MyNewMethod()
Is it possible for the service to determine if the client supports the new method before trying to call it?
I tried to use reflection but the following doesn't return null on an older client:
clientCallbackChannelInstance.GetType().GetMethod("MyNewMethod")
Is implementing my own "versioning" scheme the only way?
P.S. I don't need help architecting or implementing my own versioning scheme. I just don't want to "reinvent the wheel." ;)
Thank you.
Would wrapping the method call for the new method in a try catch block suffice? The exception caught would be the specific type you are seeing.
Example:
try
{
clientCallbackChannelInstance.MyNewMethod();
}
catch (System.ServiceModel.ActionNotSupportedException exception)
{
//new method is not supported if code reaches here
}
I have an ASP.NET 4 web-service.
It has an ImportModule action in a ModuleController controller.
That's how it works:
The user uploads a module as a CSV-file.
This file is being read using HttpPostedFileBase.InputStream and custom CSV-reading class.
This file is being transformed to a C# object according to some rules and validations. If a file is valid, then it transforms to C# object, stores in a Cache with unique GUID name and a user is redirected to CompleteImportModule action.
User checks if data is correct and he confirms uploading.
Long story short, there is a code which tells you more:
ImportModule action.
public ActionResult ImportModule(HttpPostedFileBase file)
{
if (!ModelState.IsValid)
{
return RedirectToAction("Index");
}
ModuleQuestion[] questions;
ModuleInfo moduleInfo;
string uploadId = Guid.NewGuid().ToString();
// It is my custom CSV-reader and it works. Values are assigned
FormDataCsvReader csvReader = new FormDataCsvReader(file.InputStream);
if (!csvReader.Process(out questions, out moduleInfo))
{
// File is invalid
return RedirectToAction("Index");
}
ViewBag.UploadId = uploadId;
ViewBag.ModuleInfo = moduleInfo;
ViewBag.Questions = questions;
HttpContext.Cache.Add("UploadModule_" + uploadId,
new Tuple<ModuleInfo, ModuleQuestion[]>(moduleInfo, questions),
null,
Cache.NoAbsoluteExpiration,
TimeSpan.FromMinutes(30),
CacheItemPriority.NotRemovable,
(k, v, r) =>
{
LoggingFactory.GetLogger().Debug("Removed from cache: {0}. Reason: {1}", k, r);
});
return View();
}
In View ImportModule:
// Output data from ViewBag.ModuleInfo and ViewBag.Questions
<form method="POST" action="#Url.Action("CompleteImportModule")">
<input type="hidden" name="uploadId" value="#ViewBag.UploadId"/>
<input type="submit" value="Send">
</form>
CompleteImportModule action:
[HttpPost]
public ActionResult CompleteImportModule(string uploadId)
{
var item = HttpContext.Cache["UploadModule_" + uploadId];
if (item == null) RedirectToAction("Index");
// upload module
HttpContext.Cache.Remove("UploadModule_" + uploadId);
return RedirectToAction("Index");
}
However, I met some problems. I cannot upload the module because the value is removed from a Cache right after being inserted. It is stored only for a second:
DEBUG 2015-06-22 15:00:18,696 thread 85: Added to cache:
UploadModule_c843077d-21d0-4e9f-9e5e-3df82da4bac8
DEBUG 2015-06-22 15:00:19,935 thread 48: Removed from cache:
UploadModule_c843077d-21d0-4e9f-9e5e-3df82da4bac8. Reason: Removed
The reason is "Removed" meaning that it is not expired and IIS hasn't removed it due to optimization but it looks like I removed is myself.
I am pretty sure that I am even not accessing this cache record before CompleteImportModule.
I have tried putting new StackTrace().ToString() in a CacheItemRemovedCallback. That's it, if it can help somehow:
at CPMAdministrator.Controllers.ModulesReferenceController.<ImportModule>b__9(String key, Object value, CacheItemRemovedReason reason)
at System.Web.Caching.CacheEntry.CallCacheItemRemovedCallback(CacheItemRemovedCallback callback, CacheItemRemovedReason reason)
at System.Web.Caching.CacheEntry.Close(CacheItemRemovedReason reason)
at System.Web.Caching.CacheSingle.UpdateCache(CacheKey cacheKey, CacheEntry newEntry, Boolean replace, CacheItemRemovedReason removedReason, Object& valueOld)
at System.Web.Caching.CacheSingle.Dispose(Boolean disposing)
at System.Web.Caching.CacheMultiple.Dispose(Boolean disposing)
at System.Web.HttpRuntime.Dispose()
at System.Web.HttpRuntime.ReleaseResourcesAndUnloadAppDomain(Object state)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem()
at System.Threading.ThreadPoolWorkQueue.Dispatch()
Why is it happening? Is it sort of IIS pool recycling? How can I ensure that the file is not being removed? Or how can I effictively store this data another way?
I have spent several hours finding an answer and found it right after posting a question! Let me share my experience with you.
According to my StackTrace, I understood that the cache has been cleared because the application has been ended and disposed:
at System.Web.HttpRuntime.Dispose()
at System.Web.HttpRuntime.ReleaseResourcesAndUnloadAppDomain(Object state)
All I needed is to find a reason of it.
I have opened my Global.asax file and added a Application_End method.
public class MvcApplication : HttpApplication
{
protected void Application_End()
{
}
}
It has been triggered right after view rendering success and right before cache clearing. Success! Now I needed to know the reason of application ending.
This post helped me:
There's System.Web.Hosting.HostingEnvironment.ShutdownReason
property that indicates why the application is being terminated. Its
value can be retrieved from inside Application_End().
I added a breakpoint in a beginning of Application_End and added System.Web.Hosting.HostingEnvironment.ShutdownReason to watch.
That's what it stored: BinDirChangeOrDirectoryRename.
After that, I have understood that the reason is that my log4net is writing logs right in BinDirectory. I just never knew that IIS is finishing web applications if bin directory has been changed.
I have moved my logs to a parent (application itself) folder and now it works.
It looks like I need to read more about ASP.NET.
I hope that it will help someone. Thanks to everybody who tried to help.
The reason given for removal is Removed, from the documentation that means:
The item is removed from the cache by a Remove method call or by an Insert method call that specified the same key.
So you have either explicitly called Remove somewhere else or are overwriting it with an Insert.
I am getting error "An item with the same key has already been added." I get this error randomly when many user try to access the same page on site in production at the same time.
In the code docid is passed and relevant help is displayed to user. As each user is viewing the same page so same ID is passed for all users. There is no insert operation in this call
Stack trace and souce code of mentioned line is given as follows
public string DocDescription(int docid)
{
DocumentRepository _Documentrepository = new DocumentRepository();
return _Documentrepository.GetDocDescription(docid);
}
}
public string GetDocDescription(int DocID)
{
if (DocID != 0)
return db.sysDocuments.SingleOrDefault(p => p.DocumentID == DocID).Description==null?"No Description Available":db.sysDocuments.SingleOrDefault(p => p.DocumentID == DocID).Description;
else
return "No Description Available";
}
Stack Trace excerpt:
System.Web.HttpException (0x80004005): Error executing child request for handler 'System.Web.Mvc.HttpHandlerUtil+ServerExecuteHttpHandlerWrapper'. ---> System.Web.HttpUnhandledException (0x80004005): Exception of type 'System.Web.HttpUnhandledException' was thrown. ---> System.Web.HttpException (0x80004005): Error executing child request for handler 'System.Web.Mvc.HttpHandlerUtil+ServerExecuteHttpHandlerAsyncWrapper'. ---> System.ArgumentException: An item with the same key has already been added.
at System.ThrowHelper.ThrowArgumentException(ExceptionResource resource)
at System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add)
at System.Data.Linq.DataContext.GetTable(MetaTable metaTable)
at System.Data.Linq.DataContext.GetTable[TEntity]()
at UserManagement.Models.DocumentRepository.GetDocDescription(Int32 DocID) in D:\Myproj\UserManagement\UserManagement\Models\DocumnetRepository.cs:line 109
at lambda_method(Closure , ControllerBase , Object[] )
at System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase controller, Object[] parameters)
at System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters)
at Castle.Proxies.ControllerActionInvokerProxy.InvokeActionMethod_callback(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters)
at Castle.Proxies.Invocations.ControllerActionInvoker_InvokeActionMethod.InvokeMethodOnTarget()
at Castle.DynamicProxy.AbstractInvocation.Proceed()
at Glimpse.Net.Interceptor.InvokeActionMethodInterceptor.Intercept(IInvocation invocation)
at Castle.DynamicProxy.AbstractInvocation.Proceed()
From your code and comments, I get that you store db context in a static variable. This is generally a bad idea when working with entities.
DbContext is not thread safe. So, multiple users working with your site will cause such errors in context.
The general suggestion for working with context is to prefer short lived context. So just create a new instance, when you need it, and then forget it. For the web sites, it is quite common to use inversion of control container like Unity, Castle.Winsdor etc, and configure it to return one instance per web request for your DbContext. This will give you enough performance, so all entities needed for the current request are cached, and will not cause threading issues at the same time.
See comment too, static members are application scoped variables thus they're sharing the same dictionary which can throw errors like this if multiple requests add the same key.
For some reason when I attempt to make a request to an Ajax.net web service with the ScriptService attribute set, an exception occurs deep inside the protocol class which I have no control over. Anyone seen this before?
Here is the exact msg:
System.IndexOutOfRangeException: Index was outside the bounds of the array.
at System.Web.Services.Protocols.HttpServerType..ctor(Type type)
at System.Web.Services.Protocols.HttpServerProtocol.Initialize()
at System.Web.Services.Protocols.ServerProtocol.SetContext(Type type, HttpContext ontext, HttpRequest request, HttpResponse response)
at System.Web.Services.Protocols.ServerProtocolFactory.Create(Type type, HttpContext context, HttpRequest request, HttpResponse response, Boolean& abortProcessing)
thx
Trev
This is usually an exception while reading parameters into the web service method...are you sure you're passing the number/type of parameters the method is expecting?
Also make sure your web.config is setup properly for asp.net ajax:
http://www.asp.net/AJAX/Documentation/Live/ConfiguringASPNETAJAX.aspx