Recently I upgraded a project from Framework 4.6 to 4.6.1. We started facing the following issue:
We combine all the css files to generate a common css file. During this process AjaxControlToolkit Calendar creates a WebResource.axd file. When we try to process this file then the decryption fails and Error is thrown stating : "unable to validate data".
Following code is used:
var queryString = WebResourcePath.Split(new[] { '?' })[1];
var stringBuilder = new StringBuilder();
var textWriter = new StringWriter(stringBuilder);
var context = new HttpContext(new SimpleWorkerRequest("/WebResource.axd", queryString, textWriter));
var urlEncodedData = context.Request.QueryString["d"];
var encryptedData = HttpServerUtility.UrlTokenDecode(urlEncodedData);
var machineKeySection = typeof(MachineKeySection);
var paramTypes = new Type[] { typeof(bool), typeof(byte[]), typeof(byte[]), typeof(int), typeof(int) };
var encryptOrDecryptData = machineKeySection.GetMethod("EncryptOrDecryptData", BindingFlags.Static | BindingFlags.NonPublic, null, paramTypes, null);
try
{
var decryptedData = (byte[])encryptOrDecryptData.Invoke(null, new object[] { false, encryptedData, null, 0, encryptedData.Length });
var decryptedContent = Encoding.UTF8.GetString(decryptedData).Substring(1);
var resourceParts = decryptedContent.Split('|');
Assembly = AssemblyCache.Load(resourceParts[0]);
ResourceName = resourceParts[1];
}
catch (Exception ex)
{
throw ex;
}
Error is thrown on the line : var decryptedData = (byte[])encryptOrDecry........
Some solution I went through suggested use of static machine key but we are already doing it.
NOTE : This is occuring only when we set httpRuntime targetFramework to 4.6.1 otherwise it works as expected.
From forums.asp.net:
So our problem was that some Webresource.axd requests are cached by
browsers (we didn't knew that...) but our machinekeys changes.
Fix the machineKeys in Web.config and wait for all our users to clean
their browser cache.
Comment:
https://forums.asp.net/post/5620791.aspx
Full thread:
https://forums.asp.net/t/1963234.aspx?Unable+to+validate+data+EncryptOrDecryptData+problem
Hope that helps
Related
I got an error like this when trying to add google drive service to my project. Although there is "System.Web" in the "Library" section, it cannot be used actively. Could you help?
public static string DownloadGoogleFile(string fileId)
{
DriveService service = GetService();
string FolderPath = System.Web.HttpContext.Current.Server.MapPath("/GoogleDriveFiles/");
FilesResource.GetRequest request = service.Files.Get(fileId);
string FileName = request.Execute().Name;
string FilePath = System.IO.Path.Combine(FolderPath, FileName);
MemoryStream stream1 = new MemoryStream();
// Add a handler which will be notified on progress changes.
// It will notify on each chunk download and when the
// download is completed or failed.
request.MediaDownloader.ProgressChanged += (Google.Apis.Download.IDownloadProgress progress) =>
{
switch (progress.Status)
{
case DownloadStatus.Downloading:
{
Console.WriteLine(progress.BytesDownloaded);
break;
}
case DownloadStatus.Completed:
{
Console.WriteLine("Download complete.");
SaveStream(stream1, FilePath);
break;
}
case DownloadStatus.Failed:
{
Console.WriteLine("Download failed.");
break;
}
}
};
request.Download(stream1);
return FilePath;
}
Trying to pass the current HttpContext to a static method gets tricky depending on the project framework. It's also not clear the type of project or framework you are using.
Here's a similar question that might help you clarify the difference between HttpContext when it pertains to .net and .net-core.
HttpContext in .net standard library
I have my web api that uploads and reads an excel file from the client app and then afterwards saves the data into the database, the application works perfect on locally server but the problem comes when the application is deployed to azure server it returns error 500 internal server error therefore i don't understand why this happens and and don't know how i can track to understand what might be the cause below are my code blocks.
My Interface Class
public interface UploadExcelInterface
{
Task UploadMultipleClients(Client obj);
}
My Service Implementation
public class UploadExcelService : UploadExcelInterface
{
private readonly DbContext _connect;
private readonly IHttpContextAccessor httpContextAccessor;
public UploadExcelService(DbContext _connect, IHttpContextAccessor httpContextAccessor)
{
this._connect = _connect;
this.httpContextAccessor = httpContextAccessor;
}
public async Task UploadMultipleClients(Client obj)
{
var file = httpContextAccessor.HttpContext.Request.Form.Files[0];
if (file != null && file.Length > 0)
{
var folderName = Path.Combine("Datas", "ClientUPloads");
var pathToSave = Path.Combine(Directory.GetCurrentDirectory(), folderName);
var fileName = Guid.NewGuid() + ContentDispositionHeaderValue.Parse(file.ContentDisposition).FileName.Trim('"');
var fullPath = Path.Combine(pathToSave, fileName);
var clientsList = new List<Client>();
using (var fileStream = new FileStream(fullPath, FileMode.Create))
{
await file.CopyToAsync(fileStream);
FileInfo excelFile = new FileInfo(Path.Combine(pathToSave, fileName));
ExcelPackage.LicenseContext = LicenseContext.NonCommercial;
using (ExcelPackage package = new ExcelPackage(excelFile))
{
ExcelWorksheet worksheet = package.Workbook.Worksheets[0];
var rowcount = worksheet.Dimension.Rows;
for (int row = 2; row <= rowcount; row++)
{
var Names = (worksheet.Cells[row,2].Value ?? string.Empty).ToString().Trim();
var Address = (worksheet.Cells[row,3].Value ?? string.Empty).ToString().Trim();
var Title = (worksheet.Cells[row,4].Value ?? string.Empty).ToString().Trim();
var Product = (worksheet.Cells[row,5].Value ?? string.Empty).ToString().Trim();
var Order = (worksheet.Cells[row,6].Value ?? string.Empty).ToString().Trim();
var Email = (worksheet.Cells[row,7].Value ?? string.Empty).ToString().Trim();
var Price = (worksheet.Cells[row,8].Value ?? string.Empty).ToString().Trim();
clientsList.Add(new Client
{
Names = Names,
Address = Address,
Title = Title,
Product = Product,
Order = Order,
Email = Email,
Price = Price,
}
}
//adding clients into the database
foreach (Client client in clientsList)
{
var exist = _connect.client.Any(x => x.Email == client.Email);
if (!exist)
{
await _connect.client.AddAsync(client);
}
}
await _connect.SaveChangesAsync();
}
}
}
My Controller Class
[HttpPost]
public async Task UploadMultipleClients([FromForm] Client obj)
{
await uploadExcelInterface.UploadMultipleClients(obj);
}
}
Please any help regarding this error that am getting from the server, and addition on that is it possible to get the data from the excel file without uploading it to server if yes how? because i tried adding the file to memory stream an reading it from memory but it appers not work, any suggestions thanks.
My answer may not help you solve the problem directly, but it can locate the error step by step. After we fix the error, we should be able to solve the problem in this thread.
Suggestions
Please make sure you have inclue EPPlus library in your deploy content.
Enabling ASP.NET Core stdout log (Windows Server)
Azure App Service - Configure Detailed Error Logging
Why
After tested, I am sure azure webapp can support EPPlus. For 500 error, as we don't have a more specific error message to refer to, we can't quickly locate the problem. Following the suggested method, you will surely see some useful information.
E.g:
The class library of EPPlus was not found.
Folders such as Datas are not created.
The database connection string, the test environment and the production environment may be different.
...
I have the following code in my old MVC project. I am trying to migrate it to Asp.Net Core. Anyone have the idea about how a new HttpResponse so that I can migrate the following code ?
private string RenderActionResultToString(ActionResult result)
{
// Create memory writer.
var sb = new System.Text.StringBuilder();
var memWriter = new System.IO.StringWriter(sb);
// Create fake http context to render the view.
var fakeResponse = new HttpResponse(memWriter);
var fakeContext = new HttpContext(System.Web.HttpContext.Current.Request,
fakeResponse);
var fakeControllerContext = new ControllerContext(
new HttpContextWrapper(fakeContext),
this.ControllerContext.RouteData,
this.ControllerContext.Controller);
var oldContext = System.Web.HttpContext.Current;
System.Web.HttpContext.Current = fakeContext;
// Render the view.
result.ExecuteResult(fakeControllerContext);
// Restore old context.
System.Web.HttpContext.Current = oldContext;
// Flush memory and return output.
memWriter.Flush();
return sb.ToString();
}`
I think the analogous code for what you are trying to do can be found in the answer to this StackOverflow Question: Render Razor view to string in ASP.NET 5
I am trying to load the Exchange Web Services DLL at runtime and connect to a mailbox. I am following this guide: Using Reflection to load unreferenced assemblies at runtime in C#
The code so far:
var DLL = Assembly.LoadFile(#"Microsoft.Exchange.WebServices.dll");
var theType = DLL.GetType("Microsoft.Exchange.WebServices.Data.ExchangeService");
var c = Activator.CreateInstance(theType);
var method = theType.GetMethod("AutodiscoverUrl");
method.Invoke(c, new object[] { #"anyvalid#email.com" });
After that code I am lost. How do I use the ExchangeService to bind a Mailbox object using a FolderId? EWS Managed API is not an option for my server and application.
This is the Powershell script equivalent code that I am trying to implement in ASP.NET:
$MailboxName = "account#domain"
$dllpath = "Microsoft.Exchange.WebServices.dll"
[void][Reflection.Assembly]::LoadFile($dllpath)
$service = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService([Microsoft.Exchange.WebServices.Data.ExchangeVersion]::Exchange2010_SP1)
$service.AutodiscoverUrl("anyvalid#email.com")
$mbfolderid= new-object Microsoft.Exchange.WebServices.Data.FolderId([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::Root,$MailboxName)
$MsgRoot = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($service,$mbfolderid)
Using reflection is tedious. You are on the right track though. The following code shows how you can bind to the "Inbox" folder and get the subjects of the first 10 email messages.
Notice how I use the dynamickeyword so I do not have to call MethodInfo.Invoke to call instance methods on the reflected types.
string mailboxName = "...";
// Get value for enum WellKnownFolderName.Inbox.
var wellKnownFolderNameType = assem.GetType("Microsoft.Exchange.WebServices.Data.WellKnownFolderName");
var rootFolderName = wellKnownFolderNameType
.GetField("Inbox")
.GetValue(null)
;
// Create requested mailbox and folderid for Inbox-folder for the requested mailbox.
var mailboxType = assem.GetType("Microsoft.Exchange.WebServices.Data.Mailbox");
dynamic mailbox = Activator.CreateInstance(mailboxType, new object[] { mailboxName });
var folderIdType = assem.GetType("Microsoft.Exchange.WebServices.Data.FolderId");
dynamic folderId = Activator.CreateInstance(folderIdType, rootFolderName, mailbox);
// Bind to the Inbox-folder for the requested mailbox.
var folderType = assem.GetType("Microsoft.Exchange.WebServices.Data.Folder");
var bindMethod = folderType.GetMethod("Bind", new Type[] { serviceType, folderIdType });
dynamic folder = bindMethod.Invoke(null, new object[] { service, folderId });
// Get 10 first mailitems
var itemViewType = assem.GetType("Microsoft.Exchange.WebServices.Data.ItemView");
dynamic itemView = Activator.CreateInstance(itemViewType, 10);
dynamic findItemsResults = folder.FindItems(itemView);
foreach (dynamic item in findItemsResults.Items)
{
Console.WriteLine((string) item.Subject);
}
I am attempting to create seperate workflow instances as applications in IIS7 using the Microsoft.Web.Administration dll. When it attempts to add the Application to the Site ApplicationsCollection I get a COM error: "Invalid application path\r\n"
using (ServerManager manager = new ServerManager())
{
var site = manager.Sites.Where(x => x.Name == Properties.Settings.Default.WorkflowWebsiteName).Single();
StringBuilder stringBuilder = new StringBuilder()
.Append(m_workflowDefinition.AccountId)
.Append("/")
.Append(m_workflowDefinition.WorkflowDefinitionId)
.Append("/")
.Append(m_workflowDefinition.Version)
.Append("/");
string virtualPath = stringBuilder.ToString();
string physicalPath = Properties.Settings.Default.ApplicationPoolString +
virtualPath.Replace("/", "\\");
if (!Directory.Exists(physicalPath)) Directory.CreateDirectory(physicalPath);
//Create the workflow service definition file
using (StreamWriter writer = new StreamWriter(Path.Combine(physicalPath, m_workflowDefinition.WorkflowName + WORKFLOW_FILE_EXTENSION)))
{
writer.Write(m_workflowDefinition.Definition);
}
//Copy dependencies
string dependencyPath = m_workflowDefinition.DependenciesPath;
CopyAll(new DirectoryInfo(dependencyPath), new DirectoryInfo(physicalPath));
//Create a new IIS application for the workflow
var apps = site.Applications.Where(x => x.Path == virtualPath);
if (apps.Count() > 0)
{
site.Applications.Remove(apps.Single());
}
Application app = site.Applications.Add(virtualPath, physicalPath);
app.ApplicationPoolName = "Workflow AppPool";
app.EnabledProtocols = PROTOCOLS;
manager.CommitChanges();
}
The value assigned to virtualPath is like: "something/something/something" and for physicalPath it is "c:\inetpub\wwwroot\Workflow\something\something\something". Any ideas?
Any help is greatly appreciated.
Try changing your "something/something/something" path to "/something/something/something". The IIS administration call needs the extra slash at the beginning of the path.