Upload large file to Cloud Service in Web Api - asp.net

After read below posts.
How to increase the temp folder size of web role.
Too small temp folder size of web role.
I understood there is a limitation for uploading large file to cloud service. And seems like windows azure doesn't allocate large size of space for web role by default.
So I was trying to find a way to break it. One of the ways I have been testing successfully is grasp the stream of post request and read it through block by block without reading it from the temp folder. Below is what I done. please review it .
CloudBlobClient blobClient = CreateBlobClient(account);
BlobRequestOptions options = CreateBlobRequestOpt();
CloudBlobContainer container = blobClient.GetContainerReference(sContainerName);
bool b = container.CreateIfNotExist();
CloudBlob blob = container.GetBlobReference(sBlobName);
blob.UploadFromStream(postFileStream, options);
I just passed the postFileStream which I got from Request.Files[0].InputStream in the controller of Asp.net MVC to the CloudBlobClient. and the CloudBlobClient which from Azure Storage Library SDK will read the stream block by block. In this way this will support the large file post. In my test. Even the 2GB file can works fine.
But I also want to make it work in the Asp.net Web Api. and I found the Request in Api controller is System.Net.Http.HttpRequestMessage. It is different from the one in MVC controller named with System.Web.HttpRequestBase. So How can I get the post request file stream in Web Api Controller like in the MVC controller? thanks.

You can get file content(s) using Request.Content.ReadAsMultipartAsync() method.
You can try something like this:
IEnumerable<HttpContent> contents = Request.Content.ReadAsMultipartAsync(new MultipartMemoryStreamProvider()).Result.Contents;
foreach (var content in contents)
{
//...
//create your blob object...
//...
blob.UploadFromStream(content.ReadAsStreamAsync().Result);
}

Related

in Xamarin/App how do I Secure Files on ASP.NET Restful Server in folders from other users and general public

I have an APP using restful server. I want to store PDF's, images, etc. in folders on my server. How can I make the folders private on server, yet allow App to access only certain folders depending on their app access.
I have different users in app and security/tokens established, etc. But if they upload an image for their avatar (and now PDF's), they get stored in folders on the server, and I just display with image source=https://blahblah.com/org1/images/user232.jpg.
How can I make that not accessible to outside (like just going to browser), yet make accessible to app if they have correct login privilege's for that organization/user? And then further extend that logic to more sensative PDF's, and other docs uploaded through app. I didn't want to store in SQL since then harder to use simple image display tools and I already have upload and media managers using folders structures.
I can see how to secure if logging onto server through browser (credentials), but can't see how you connect App with that security level and maintain it for the session.
For future readers. Most of the work was done on the restful (ASP.NET) side. I first tried using authorization/Authentication in web.config and having Allow and deny. This allowed a redirect of a user to a login page; however, it didn't do it if they entered an image exactly correct on website.
Found HTTPHandlers (adding in webconfig ) where I could write code that would be executed once the user entered the specific Image address xyz/abc/image.png. I found this a bit feeling like a hack.
So lastly modified my
routes.MapRoute(
name: "staticFileRoute",
url: "publicstor/{*file}",
defaults: new { controller = "Home", action = "HandleStatic" }
And add a function like this to home controller.
[System.Web.Http.HttpGet]
public ActionResult HandleStatic(string file)
{
if (Session["OrgId"] == null) //todo need to add full security check.
{
return View("Login");
}
else //Either coming from app or coming from web interface
{
string mimeType = MimeInfo.GetMimeType(Path.GetExtension(file));
return File(file, mimeType);
}
}
The final bit is on the Xamarin side to now pass security when getting an image. Since just a simple Xamarin.Forms.Image doesn't have a way to pass login info or tokens/authentication I used
https://forums.xamarin.com/discussion/145575/image-from-url-needing-auth
And established an appwide webclient that logged in generally once forcing my restful to go through security validation, then just accessed the images/documents through out my app from that webclient. So far so good. Hopefully there are no holes.
This gives the gist to a future reader.

Is it possible to restrict access to REST API built using Web API 2?

I built a REST API using ASP.NET Web API 2, so I could deliver data from a backend database to my applications running on any platform (mobile, web, desktop etc) However up until now, I simply call the website with the controller I need data from and that's it, it sends back the JSON string in the response.
But, the data is kind of special, and there is nothing to prevent another developer from simply calling the controllers and getting back the exact same data and building their own application around it.
My question is - is there anyway to restrict access to the API so that only my applications can get valid response from the server. (i.e. prevent other developers from using my REST API)
I already read these documentation Security, Authentication, and Authorization in ASP.NET Web API I'm just not sure which of these scenarios apply to me, or if any will do what I am asking.
EDIT - Another piece of info, my web service is running on Azure in case it is relevant.
Did you happen to check token based authentication?Please go through https://stackoverflow.com/a/38670221/4868839 and https://www.youtube.com/watch?v=rMA69bVv0U8 must be a good to start with.
there are different way to validate your web api.
Authentication Filters in ASP.NET Web API 2
using you can customise your authentication filter
you can refer sample Reference link
Token Based Authentication using ASP.NET Web API 2, Owin, and Identity
//App_Start/Startup class
public void ConfigureAuth(IAppBuilder app)
{
OAuthAuthorizationServerOptions OAuthServerOptions = new OAuthAuthorizationServerOptions()
{
AllowInsecureHttp = true,
TokenEndpointPath = new PathString("/v1/accesstoken"),
AccessTokenExpireTimeSpan = TimeSpan.FromDays(AppConfiguration.AccessTokenExpireDuration),
Provider = new SampleOAuthProvider() // class that override your method
};
// Token Generation
app.UseOAuthBearerTokens(OAuthServerOptions);
}
You can find reference from inherits Default implementation of IOAuthAuthorizationServerProvider used by Authorization
i hope it sholud helps you thanks.

Client application login using httprequest

I am a bit new to ASP.NET and web development, and I am still confused about the following :
On the one hand I have a very complete ASP.NET MVC website based on NopCommerce that includes login, registration, e-commerce features, forums, etc.
On the other hand, I have a Windows Forms client application that needs to read and write data from and to my website database.
The first thing I would need to do is to allow users to login in the client application by sending a request to the server. I've been looking around the web for days and I can't manage to find a precise and secure way to do so.
I'm pretty much sure that I have to use System.Net.Http to make a request from the client. Will this request then got to be handled by a MVC controller action ? Maybe an already existing one ?
Here is the method I have so far, based on a tutorial found online (it is not complete at all) :
private static async void PostRequest(string addressPost)
{
IEnumerable<KeyValuePair<string, string>> queries = new List<KeyValuePair<string, string>>()
{
new KeyValuePair<string, string>("Query1", "Email"),
new KeyValuePair<string, string>("Query2", "Password")
};
HttpContent formContent = new FormUrlEncodedContent(queries);
using (HttpClient client = new HttpClient())
{
using (HttpResponseMessage response = await client.PostAsync(addressPost, formContent))
{
using (HttpContent content = response.Content)
{
string myContent = await content.ReadAsStringAsync();
System.Diagnostics.Debug.WriteLine(myContent);
}
}
}
}
Any existing example or help would be greatly appreciated.
first we need to focus on the architecture of the application, we have here two applications, 1) web application, 2) WinForm application. and you want to share the same db for both, here are the drawbacks of doing so, you might found yourself one day your winform will lock a table because of updating etc, and your web application will lose access, thats not a good idea,
here is how i would do it.
create a web api plugin for your web application, and use api tokens for security, there is some available web api plugin for nopcommerce but its limited in functionality, so i guess you will have to add some methods based on your needs, next thing you will do is have your winform application communicate with your webapi, in that case your winform works independently and secure,
as a side note, you can have in your web api multiple tokens for each user if you want, you can manage that in your web api plugin, just make a table where you will store that info with user info and tokens for everyone and you can manage that from the web admin.

Restful Web API from Browser

I am using ASP.NET MVC 4 WEB API to create a Restful API service. This is my first go at it, so if you feel I am taking a wrong approach please feel free to correct.
I want to create a rest API (only & not a website, the consumer of the api can decide where they want to consume it), in the past I have used Restful WCF service to achieve this.
I have created a new ASP.NET MVC 4 Web Application and chose the WebAPI project template. I have added a controller class 'CatalogueController.cs' the purpose is on Get() operation I want to return the Catalogue list. The CatalogueDo contains only one property 'Service' of type string.
[System.Web.Http.HttpGet()]
public HttpResponseMessage Get()
{
return Request.CreateResponse(HttpStatusCode.OK, Catalogue);
}
When I run the application the browser loads with the URL http://localhost:5502/ resource not found, if I add the controller name http://localhost:5502/Catalogue/ the browser pops open a notepad with,
[{"Service":"Exchange"},{"Service":"Holidays"}]
The data is correct but
the browser keeps showing resource not found and after my request has been served the URL changes to http://localhost:5502/.
Question,
Am I doing something wrong? Should the response that pops up in the
notepad not be shown as xml in the browser it self?
Why does the controller name get removed from the URL once the request has been served?
Is it at all possible to invoke this REST service from Excel or Power Pivot?

ASMX Service and Lack of Crossdomain.xml file

I have an issue with an asmx service I am trying to access. No crossdomain file. I read there is a way around this using HTTPService instead of a webservice. Still cannot load the wsdl. See code below. Any help would be greatly appreciated:
var dataService:HTTPService = new HTTPService();
dataService.url =
"http://flexmappers.com/proxy.php?url=http://www.server.net/carbon.asmx";
dataService.method = "POST";
dataService.addEventListener("result", onCarbonCalcResult);
dataService.addEventListener("fault", onCarbonCalcFault);
//dataService.resultFormat = "xml"
var params:Object = new Object();
params["call"] = "getCarbon";
params.area = carbonarea;
params.geojson = geojson;
dataService.send(params);
No crossdomain file. I read there is a
way around this using HTTPService
instead of a webservice
It sounds like you were misinformed.
In browser based applications, neither HTTPService, WebService, and RemoteObject tags are not allowed to access content on a remote server unless a crossdomain.xml file exists allowing such access. They can all access content on the same domain as the SWF without a crossdomain.xml file in place.
To get around this, you can use an HTTP Proxy on the same server that serves your SWF. You could also use an AIR app which does not run in a browser, and therefore exists in a different security sandbox.
You can create your own proxy with BlazeDS or Apache HTTP.

Resources