How to persist a file between controllers using C# MVC? - c#

I asked a previous question here and one part of it seems to be a whole subject in itself.
I am attempting to preserve a files data across controller calls.
The scenario is: A user uploads a file containing entries to be submitted to a database. If the file has warnings and errors they'll be redirected to a validation page. If there are no warnings or errors their file will be directly processed.
If the user receives warnings but no errors (ie. a text field is too long and will be truncated) they can still import the file. As there are two separate screens between uploading the file and sending it to the database the file data will need to be preserved.
I have seen a dozen similar questions to this but none of them seem to have relate-able answers (so please don't mark this question as a duplicate if a similar question doesn't have an answer to this exact problem).
My first idea was to save the file using the uploaded file name + a guid and saving that file name to the session state, but the answers I got on my previous question were all pretty adamant that this was a terrible solution.
The solutions I have found to other similar questions:
Reupload the file (a terrible solution)
Using a viewbag to send the file name to the view, to be sent back to the second controller (doesn't sound right)
Save the file location in the view model to be sent to the view, to be retrieved again by the second controller (again doesn't sound right)
Save the file location in the session or in temp data (receive generally unfavorable remarks)
I have done my research and cannot find the best way to go about this. Can someone please help me? If you think another question answers this, can you please send it to me as an answer instead of reporting this as a duplicate as I have already done quite a bit of searching.
Thank you,
Samuel Davis
EDIT: my users do have a session available. Another solution I could think of is appending a hardcoded string to the GUID contained within their session ID eg. "MyImporter-xxxx.xxxx.xxxx.xxxx.csv". This way "MyImporter" could be a private constant string, and my controller wouldn't have to persist any identifier. I am unsure of any downsides to this method, but as I am pretty fresh to MVC there should certainly be cases that I haven't thought of.

The best would be to store the location of the file on your server. Session or database.
Flow:
User uploads a file
The server stores the file in a some location on the server and stores the location of this file in a Session variable or in the Database
The user sends a second request
The server retrieves the location from the Session or the Database.
The server does something with the file
It's worth mentioning that if you decide to store the file location in a database, you should also store the currently authenticated user in the same table so that you could later retrieve the correct record. If you are not using authentication that might not be a good solution because you will not be able to retrieve the record. In this case you could use a hard to guess identifier in the database to store the file location under. Then this identifier will be passed to the view (under the form of a view model of course) and passed on subsequent request. It is important that this identifier is difficult to guess to avoid one user working with the files of another user.
Another possible solution might be to store the location of the file in an encrypted cookie which will be sent on subsequent request.

Have you heard of TempData? Its like a self-destructing session value.

Related

Need some inspiration on how to generate and stream images efficiently on Azure with C#

I have a situation where I need to display an image to an end user following the below method.
When the user request the image from a URL, the C# code behind should start by looking in an azure blob/cdn to see if the image is there. If the image is there and less than x days old, it should pass the image to the end user in the most efficient way (preferably without spending too many resources (memory & cpu) passing it to the user.
If the image is not there or more than a week old, the image will be generated based on the parameters supplied in the url the user requested, after which it is stored on the blob/cdn and displayed to the end user.
My problem is how, I in the most efficient way on azure, can generate a lot of images simultaneously as well as being able to pass the data from the cdn while still being able to first check if it is too "old" and needs to be regenerated or if it isn't there and needs to be generated before being displayed to the user. Since the second I pass the image through the c# code will loose the cdn's strengths.
There are many ways to do things on azure. You will need to look through the extensive azure documentation and determine what will best fit your needs.
If you want to get something working quickly azure blobs can be served directly to a client (straight to their browser) - see the doco keep in mind anonymous access is not secure.

Implementing an Auto LogIn link (and ending the session right after that)

Currently I'm trying to implement an auto login link for the emails sent from the site.
One of the requirements is that the user is able to see the link but not the rest of the site unless he manually logs in.
My current problem is that I cannot get the logout part right. The current flow goes something like this:
Check if the user is logged in
If not, check the url query string and do some calculation to check
the code
If everything is alright I log the user in, update the CurrentUser
and all the Session object
Then I need to use HttpContext.Response.Redirect() because the way
the system is made (as far as I have read using Redirect is a quite
abrupt way to cut the Request, but my current issue is that the
system will keep checking other things and redirect me to the LogIn
page if I don't cut it here)
At this point the user is Logged In
If they click on a new link inside the page, on this new Request it will check some Session properties
created on step 4 and if they exist it will log the
user out.
My problem is that it works some times and some other times it doesn't. A pretty consistent thing I notice is that is not working when I open the link in a new browser instance, but generally works when opening on an already open browser.
I guess something could be happening with the Session object between the Redirect and the new Request specially on a new browser instance, but not sure why.
Edit: The problem is happening on step 6
I'm not sure if i totally understand your question, but here are some ideas related to session problems.
Probably when opening the new instance a new Session is created. Therefore your data is gone.
A work around might be storing the needed values in the cache. This is dangerous because cache items can be deleted if iis thinks there is not enough memory.
https://support.microsoft.com/en-us/kb/323290
Another workaround might be saving the needed values in a database.
Or send the needed data through the headers.

The Url where we type in address bar must not be accepted

Hello All I need all your help badly. We have made a role,ID based application in asp.net(C#) where the menu appear as per his roles. This is fine now the users are trying to directly type the link in address bars and using them. Cant restrict them in page loads and sessions as this is a production site which is already slow. So my intension is to show the url in encrypted format which expires in certain time where the user cant copy and paste it. Is there any possible way...
Cant restrict them in page loads and sessions as this is a production site which
is already slow.
Fix that crappy code and / or add more servers. Because this is the ONLY way it makes sense to do it. Anything else is the type of security that gets broken into and then you run around blaming the world for being unfair.
So my intension is to show the url in encrypted format which expires in certain
time where the user cant copy and paste it.
? So the menu has an encrypted URL that is only valid like for half a second? What if the user browses the source code of the page? He can see all the source there.
This is not security, it is hogwash. Sorry to be blunt, but this is not going to work and you are making a bad job here.
Checking this in page load will take less than a millisecond (assuming you cache roles in the session). WAY less.
Check for user role in page_load event and if the user does not have permission then redirect him to a page showing permission denied.
Please provide code if you need further help.
Yeah.... you've painted yourself into a corner here.
Short answer:
No, there's no clean way to do this and whatever type of 'special' url implementation you create will be open to abuse/spoofing and still require you to add code anyway.
Long answer:
I can't see any viable solution other than injecting some code into Page_Load.
I take it you're not using WIF/Claims-based security, just some bespoke written user login, database store based code? So your best approach (at this point) is to make a simple class in App_Code: When the user logs in, load their permissions into something like a DataTable and store that in a session variable. That way you can avoid doing database requests every time the page loads/posts back, this'll probably speed your site up a bit too.
Build a non-static method in a class that is to be used on Page_Load, where this will get the URL (or page id) being accessed, then check that against the session stored DataTable. If that check fails redirect them to an access denied page.
Building the class foundation is key, don't attempt to shortcut and copy-paste chunks of code into each page. With the 'security' class you can standardise your code and reduce testing down to a few simple checks.

Accessing Pdf file from Database using MVC4 Asp.Net

I am stucked in a situation working from 2 days, tried searching many sites
for the solution couldn't find anything including Stackoverflow,
WHAT I NEED
I am working on MVC, and I have a Byte array file which is already saved in database(SQL) and I need to access the file from database, and display it into PDF file, there is not Writable task to do, just Readable from database.
WHAT I DID
->Wrote Javascript to get the ID's of the give information.
->on click of "Download" button called method in JS, and made redirect to Controller with the ID's I need (which is good till now!!) (PIC 1)
->Generated Stored Procedure to access all column information based on the ID's (PIC 2)
ScannedResult is the column where the value has been stored, and I need to access that file.
WHAT I COULDN'T FIND
-> Couldn't able to find a way to access that byte array and display into PDF!!
-> as in shown in PIC4, while debugging it shows the error message "Failed to convert parameter String to Int64", and I do know what does that error mean, I just want to give some more information here, the ID's I am getting is "BigInt" and I am passing it as String(see in Controller), Reason behind for this, there might be having multiple ID's in single shot, so using "," (PIC 3) in the middle of all ID's, so I have planned to convert into "String" or If any body have greater suggestion I am all yours to listen,
UPDATE1
Please help me to find out this issue, answers will be appreciated.

prevent users from showing XML file on server .NET

I'm building a trivia game that retrieve questions from XML file using javascript.
But the XML file is available to those who got the full path to the XML file.
How can i prevent users from showing the XML file ?
Thank you.
If it's going to be available to the client via Javascript, it's got to be available to the client in general. Now you could encrypt it, then decrypt it in the Javascript - but that's more of an obfuscation technique than anything else... basically if you need the browser to have the plaintext version of the file at some point, you can't prevent it from being available to users in general.
If the problem is that the file contains both questions and answers - i.e. data that you're happy for users to see and also data that you don't want them to see - you should split the file in two.
If you only want users to be able to see the data at the right time (i.e. when the question is asked) then you can introduce a server-side aspect which will serve one question at a time, when requested, and log that the user has just seen the question. That won't stop users from fetching questions, but it will stop them from doing so in advance without you being aware of it. (Unless, of course, they can log in as a different user, fetch the questions, work out the answers, then log in as their real account and give all the right answers. At that point it's more a matter of authentication and user control than anything else - after all, they could take the test twice, too...)
I don't know your game software flow, but I think you have to write a web service which enforces validation rules over the XML files (stored in non publish web server are).

Categories