.NET Core 5 GET Action Called Twice - session

Environment
.NET Core 5 Web Application
IIS 10
Azure VM
Issue
Executing a GET action results in that action being called a second time. The first call shows cookie information. The second does not show cookie information.
What we've tried:
Occurs for GET requests but not POST requests
Occurs without a view (NOT a javascript issue)
Browser does not show two requests. This occurs server-side.
Does not occur in Firefox Privacy Mode
Does not occur on localhost. Only in production.
Occurs with HTTPS off
Fork of the solution does not exhibit this behavior (makes middleware unlikely cause)
Best guesses:
.NET 5 (deprecated) or dependencies (a bad developer blames his tools)
IIS Settings
Session
Code example:
Controller
// no other filters
[HttpGet]
public IActionResult DupeRequestTest()
{
// database insert with Dapper
var sql = #"INSERT INTO TrackingTable
(CookieJson, CreateDate)
VALUES(#CookieJson, GETDATE());";
using var con = new SqlConnection(_connectionString);
con.Open();
con.Execute(sql, new
{
CookieJson=JsonConvert.SerializeObject(Request.Cookies),
});
// returning a status code so no View, javascript, or other requests
return StatusCode(200);
}
Database results:
CookieJson
CreateDate
[{"Key":"SessionId","Value":"ac6f292c-1ca1-5179-9123-78a04d382dea"}]
2022-10-25 09:46:30.523
[]
2022-10-25 09:46:30.770
Thank you. Any help, such as next testing steps, would be appreciated - short of building a new app.
I'm sure the answer is either very stupid or very hidden.

Related

Http Post - long delay at state ExecuteRequestHandler

I have an asp.net mvc website hosted on Windows Server 2012r2 Standard which uses KnockoutJS to display data in a grid. This server is dedicated to the process that I'm having trouble with - it does not server any other requests.
An ajax call is made to a "GetRecords" action of a controller. This returns data for a couple of dozen records very quickly.
The user is able to make amendments to the data and submit for update. The knockout code makes another ajax call, this time posting the records. At this point the site "hangs" for a long time (over 10 minutes), but it does complete successfully and the updated date is persisted to a database. During the "hang time" the CPU for the IIS Worker Processes hovers around the 50% mark.
I'm trying to figure out what's causing the delay. It seems that the delay happens before the first line of code of the controller action is reached. I've added trace statements to the action and I can see that once the 1st line is executed, then the action completes within a couple of seconds.
From the IIS manager, I've drilled in to "Worker Processes"\"Current Requests" during the time the page is "hung", I can see that the State is listed as "ExecuteRequestHandler" and the Module Name is "ManagedPipelineHandler". There are no other "Current Requests" displayed.
Using the Chrome dev tools, I've captured the json being posted for the update, it is approx 4mb in size.
I've ruled out the problem being caused by bandwidth because I've tested from a browser running locally (on the web server), and I get the same delay.
Also, when I post the same number of records on the same site hosted on my dev VM then it works fine - completes end-to-end in under 3 seconds.
Any suggestion on steps I can take to improve performance of the post?
I have created a process dump of the IIS worker process when it is in the "hanging" state, this is available at: onedrive link
It seems that "Thread 28" is causing the issue, since this has a "Time spent in user mode" value of over 2 minutes. I requested the process dump about 2 minutes after making the http post request from the website. The post did eventually complete ok after about 20 minutes
Able to work around this problem bypassing the MVC model binding. The view model param (editBatchVm) that was passed into the controller method has been replaced. So, instead of:
public void ResubmitRejectedVouchersAsNewBatch(EditBatchViewModel editBatchVm)
{
I now have:
public void ResubmitRejectedVouchersAsNewBatch()
{
string requestData = "";
using (var reader = new StreamReader(Request.InputStream))
{
requestData = reader.ReadToEnd();
}
EditBatchViewModel editBatchVm = JsonConvert.DeserializeObject<EditBatchViewModel>(requestData);

How to access session from a view in ASP .NET Core MVC 1.0

I am trying to access session data from inside a view.
Use Case: I'm storing status messages in the session that will be displayed at the top of the page. Currently I implemented this by using a DisplayMessages() function that sets some ViewData[....] properties and calling it at the beginning of every controller action.
Goal: I want to only set the status message once without needing additional code in the controller to display the messages on the next page load.
So I'm trying to access the messages that are stored in the session directly from the view.
So far I have tried the following:
Dependency Injection of an IHttpContextAccessor (doesn't seem to work anymore with ASP .NET Core MVC 1.0.0
Creating a static class to access the session, including the change from next() to next.invoke() suggested in the comment
This didn't work. I could access the HttpContext and Session.IsAvailable was true, but there was no data in the session.
The following should work in the view: Context.Session.TryGetValue
If you are using the SessionExtensions then Context.Session.GetString will work.
Injecting IHttpContextAccessor does work, but starting with ASP.NET Core 1.0.0 RC2, the IHttpContextAcessor is not registered by default, because it has significant performance overhead per request. See this GitHub announcement for more information.
Tratcher posted:
IHttpContextAccessor can be used to access the HttpContext for the current thread. However, maintaining this state has non-trivial performance costs so it has been removed from the default set of services.
Developers that depend on it can add it back as needed:
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
But in your use case, I would suggest using a ViewComponent, which is a reusable piece of View with logic, that do not depend on a controller.
The documentation can be found here.
In your Views you would simply embed it with
#await Component.InvokeAsync("PriorityList", new { maxPriority = 2, isDone = false })
or
#Component.Invoke("PriorityList", new { maxPriority = 2, isDone = false })
for synchronous calls.

IIS Express Returning HTTP 400 for WCF RESTful Service

I have a WCF RESTful Web Service (using webHttpBinding) that is returning a 400 when I try to call a web service method on it.
If I go to mywebservice.svc, I get the standard WCF web service page. But if I go to /mywebservice.svc/some/rest/service/url, I get an Http 400. Every single time. Doesn't matter the parameters, or the method being called.
Here's what we've looked at so far:
Looked at IIS Express logs. There is no Win32 status (i.e. status 0) to go along with the HTTP Status
Turned on WCF logging. Nothing is logged by WCF, which suggests the request isn't even making it that far.
Tried debugging our method, but the breakpoint never gets hit.
Tried running the service under Cassini. Same result (http 400).
Tried another user on the problematic machine. Same result.
We know that this works on other machines. The problematic machine is using VS 2010 on Win XP. We are using WCF 4.0
I know there isn't much to go on here because we don't have a specific error message, but given where we've looked, does anybody have any suggestions on where to look next?
UPDATE: Added Code Samples
Here is the definition of my with one method, and the implementation of that method.
[ServiceContract]
public interface IMAMDataWebService
{
[WebGet(UriTemplate = "/Contracts/{taxID}", ResponseFormat = WebMessageFormat.Json)]
[OperationContract]
ContractCollection Contracts(string taxID);
}
public ContractCollection Contracts(string taxID)
{
ContractCollection contracts = new ContractCollection();
try
{
contracts = _contractService.GetContracts(taxID);
}
catch (RstsException rEx)
{
if (!rEx.Logged)
_errorLogger.LogError(rEx);
WebFault.ThrowFault(rEx, HttpStatusCode.InternalServerError);
}
catch (Exception ex)
{
RstsException rEx = new RstsException(ex);
_errorLogger.LogError(rEx);
WebFault.ThrowFault(rEx, HttpStatusCode.InternalServerError);
}
if (contracts.Count == 0)
{
WebFault.ThrowFault(Strings.ObjectNotFound, HttpStatusCode.NotFound);
}
return contracts;
}
I'm calling it with a web browser, i.e. MAMDataWebService.svc/Contracts/123456789
I'm convinced this has to be a permissions problem, but I"m not sure what. It works on all our Win 7 machines using VS 2010, but a few users still have XP and they're the ones with the problem. But without any errors, it's hard to tell what's going on.

MVC Null exception after deploying to web server

I have an MVC 3 application that works fine when running locally from visual studio,
There are two bat files that pre compile the application ready for deployment, when i run the bat files and upload the deployment folder to the web server a load of errors are thrown including a null exception error,
The error can be seen by visiting the following URL, i can also provide the full stack trace on a document if required, i didnt want to post it here as its so big.
error can be seen here
I cant understand where the error is coming from as everything works locally, t seems these errors are being created when the bat files are compiling the application, has anyone had similar experiences after deploying an MVC app? can anyone offer any advice on what may be causing the problem?
Thanks
Liam
UPDATE=============
This is the GetTax method, this code has been thoroughly tested as its part of NopCommerce 2.2, the errors only occur after the solution is compiled via the BAT files which is again standard for building a nop commerce 2.2 app, am i right in thinking its got to be something on my machine that is causing these problems when the BAT files are ran and the code is compiled for deployment?
public virtual decimal GetTaxRate(ProductVariant productVariant, int taxCategoryId,
Customer customer)
{
//tax exempt
if (IsTaxExempt(productVariant, customer))
{
return decimal.Zero;
}
//tax request
var calculateTaxRequest = CreateCalculateTaxRequest(productVariant, taxCategoryId, customer);
//make EU VAT exempt validation (the European Union Value Added Tax)
if (_taxSettings.EuVatEnabled)
{
if (IsVatExempt(calculateTaxRequest.Address, calculateTaxRequest.Customer))
{
//return zero if VAT is not chargeable
return decimal.Zero;
}
}
//active tax provider
var activeTaxProvider = LoadActiveTaxProvider();
//get tax rate
var calculateTaxResult = activeTaxProvider.GetTaxRate(calculateTaxRequest);
if (calculateTaxResult.Success)
return calculateTaxResult.TaxRate;
else
return decimal.Zero;
}
The stack trace indicates that it's coming from the method GetTaxRate in TaxService.cs. I'm guessing this isn't anything ASP.NET MVC specific, but a deployment issue. It could be database permissions or connection strings.. you'll have to check what that method is doing.
Nop.Services.Tax.TaxService.GetTaxRate(ProductVariant productVariant, Int32 taxCategoryId, Customer customer) in c:\Nop 2.2 Source\just4fashion2.2source\Libraries\Nop.Services\Tax\TaxService.cs:240
It probably has something do with a configuration mismatch between your development and production environment.
If you look at the top of the stack trace you see that is has probably nothing to do with MVC but with someting in your TaxService.
[NullReferenceException: Object reference not set to an instance of an object.]
Nop.Services.Tax.TaxService.GetTaxRate(ProductVariant productVariant, Int32 taxCategoryId, Customer customer) in c:\Nop 2.2 Source\just4fashion2.2source\Libraries\Nop.Services\Tax\TaxService.cs:240
You need to check on which element the Null exception occurs.
Things to check:
Is productVariant null?
Is customer null?
Are there any other elements accessed in this function like a Repository or Factory that could be null?
Are there any configuration changes between local and production like connectionstring, logging or security settings?

First try wcf data service always times out from client

I have read all other posts and have been googling this for the last 2 hours! I started WCF Data Services about 3 hours ago btw.
My service is on an asp.net4 app, the ado entity model exposes an sql server db.
Here is FasDataService.svc.cs
public class FasDataService : DataService<FASStoreEntities>
{
public static void InitializeService(DataServiceConfiguration config)
{
config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2;
config.UseVerboseErrors = true;
config.SetServiceOperationAccessRule("*", ServiceOperationRights.All);
config.SetEntitySetAccessRule("*", EntitySetRights.All);
}
}
I have then a winforms 4 app with the following code in the Main()
FASStoreEntities fas = new FASStoreEntities(u);
var a = from al in fas.Customers
where al.Name == "Alinio"
select al;
MessageBox.Show(a.First().Phone1);
When I run the web app and point to http://localhost:15995/FasDataService.svc/Customers(1) it loads up the one and only customer in there
My error is WebException was unhandled:
The operation has timed out. The inner
exception is null.
Also, everything is local but when I do this (in chrome) it takes a good load of time! Its scary to think of how it would perform in production?
For some reason, today I installed fiddler and tried it and it works! I also, queried the service with linqpad and it worked no prob!
Although throughout today I played with wcf data services and had tons of problems accessing data because of all kinds of errors, data connection was still open, some error insert excess data in a field etc etc.
Fiddler was very helpful at diagnosing what the error was, its very difficult to figure out what really went wrong so fiddler is a must have.

Resources