I am working on uploading files with a WCF web service,
here's my code for uploading:
public string UploadTransactionsFile(string uploadPath)
{
string uploadTransactionsFile;
if (String.IsNullOrEmpty(uploadPath))
return string.Empty;
if (!ValidateTransactionsFile(uploadPath))
return string.Empty;
try
{
var dir = #"C:\Upload\";
string myUploadPath = dir;
var myFileName = Path.GetFileName(uploadPath);
CheckDirectory(myUploadPath);
var client = new WebClient { Credentials = CredentialCache.DefaultCredentials };
client.UploadFile(myUploadPath + myFileName, "PUT", uploadPath);
client.Dispose();
uploadTransactionsFile = "ok";
}
catch (Exception ex)
{
uploadTransactionsFile = ex.Message;
}
return uploadTransactionsFile;
}
I created a Windows Forms test client and added the service reference, but
my code in calling the method and hardcoded the file i want to upload:
private testServiceClient testService;
private void Button_Click(object sender, RoutedEventArgs e)
{
var File = "C:\\file.csv";
testService = new testServiceClient();
testService.UploadTransactionFile(File);
}
I can upload files using one computer, but when I put my test client to another computer, then I can't, because the file is just passing the stringpath, which cannot be found on server computer.
Am I missing something?
Do I have to send my file as byte[]? If so, then how do I do this?
To stream files over HTTP to WCF service:
http://www.codeproject.com/Articles/166763/WCF-Streaming-Upload-Download-Files-Over-HTTP
However, WebClient class is designed to be used on the client side too. So you could bypass the WCF service altogether.
From MSDN:
Provides common methods for sending data to and receiving data from a
resource identified by a URI.
Related
Hello legendary coders.
Flowing by my previous question I tried to use user32.dll in windows universal application (UWP) in C# language but I encountered an error while trying to use the method I imported from that .dll
here is my code:
[DllImport("user32.dll")]
public static extern bool LockWorkStation();
private async void btnLock_Click(object sender, RoutedEventArgs e)
{
string path;
if (Images.TryGetValue(selectedRadioButton.Name, out path))
{
StorageFile file = await StorageFile.GetFileFromPathAsync(path);
await LockScreen.SetImageFileAsync(file);
if (!LockWorkStation())
throw new Exception(Marshal.GetLastWin32Error().ToString());
}
}
as you can see I imported LockWorkStation() mthod from user32.dll and I used it in the event listener of a button. the Images is a Dictionary<string,string> and every thing is Fine unless the call to method LockWorkStation() it always return false and so the thrown error is 1008 I mentioned it in the Title The question is Why? and how can I assign a token?
Note: any way,any way to lock the screen is admirable.
So after searching a lot and being hopeless from directly lock the screen from the universal windows application platform I send a web request to a local web server and I made that web server to use the user32.dll and lock the screen.
here is the code in the UWP app:
try
{
HttpClient httpClient = new HttpClient();
Uri uri = new Uri("http://localhost:8080/lock/");
HttpStringContent content = new HttpStringContent(
"{ \"pass\": \"theMorteza#1378App\" }",
UnicodeEncoding.Utf8,
"application/json");
HttpResponseMessage httpResponseMessage = await httpClient.PostAsync(
uri,
content);
httpResponseMessage.EnsureSuccessStatusCode();
}
catch (Exception ex)
{
throw ex;
}
and there is the code in the web server:
[DllImport("user32.dll")]
public static extern bool LockWorkStation();
private static string LockTheScreen(HttpListenerRequest request)
{
var inputStream = request.InputStream;
try
{
using (StreamReader sr = new StreamReader(inputStream))
{
JToken pass = JToken.Parse(sr.ReadToEnd());
if (pass.Value<string>("pass") == "theMorteza#1378App")
{
LockWorkStation();
}
}
}
catch (Exception)
{
return "fail";
}
return "fail";
}
Note: you can find how to make a simple web server here
But: you must install the web server and grant it's access for users.
Our system has been used to upload millions of files over several years. The clients use the following code to send an authentication token and zip file to our WEB API on Windows Server 2008 R2. On our Windows 7 devices, the system works great. As we are attempting to move to Windows 10 devices, we have suddenly encountered an issue where the received file has blocks of data in a different order than the source file. The problem only occurs about half of the time, which makes it very difficult to track down.
client code (.NET 4.5)
private static void UploadFile(string srcFile, string username, string password)
{
if (File.Exists(srcFile))
{
ConnectionUtilities connUtil = new ConnectionUtilities();
string authToken = connUtil.GetAuthToken(username, password);
using (HttpContent authContent = new StringContent(authToken))
{
using (HttpContent fileStreamContent = new ByteArrayContent(File.ReadAllBytes(srcFile)))
{
FileInfo fi = new FileInfo(srcFile);
using (HttpClient client = new HttpClient())
using (MultipartFormDataContent formData = new MultipartFormDataContent())
{
client.DefaultRequestHeaders.ExpectContinue = false;
formData.Add(authContent, "auth");
formData.Add(fileStreamContent, "data", fi.Name);
var response = client.PostAsync(ConfigItems.hostName + "UploadData", formData).Result;
if (response.IsSuccessStatusCode)
{
File.Delete(srcFile);
}
}
}
}
}
}
WEB API code (.NET 4.5.2)
public async Task<HttpResponseMessage> PostUploadData()
{
if (Request.Content.IsMimeMultipartContent())
{
MultipartFormDataStreamProvider streamProvider =
MultipartFormDataStreamProvider(HttpContext.Current.Server.MapPath("~/app_data"));
await Request.Content.ReadAsMultipartAsync(streamProvider);
string auth = streamProvider.FormData["auth"];
if (auth != null)
{
auth = HttpUtility.UrlDecode(auth);
}
if (Util.IsValidUsernameAndPassword(auth))
{
string username = Util.GetUsername(auth);
foreach (var file in streamProvider.FileData)
{
DirectoryInfo di = new DirectoryInfo(ConfigurationManager.AppSettings["DataRoot"]);
di = di.CreateSubdirectory(username);
string contentFileName = file.Headers.ContentDisposition.FileName;
di = di.CreateSubdirectory("storage");
FileInfo fi = new FileInfo(file.LocalFileName);
string destFileName = Path.Combine(di.FullName, contentFileName);
File.Move(fi.FullName, destFileName);
}
return new HttpResponseMessage(HttpStatusCode.OK);
}
}
return new HttpResponseMessage(HttpStatusCode.ServiceUnavailable);
}
The problem initially manifests as a zipped file that can't open in Windows. Only by doing a hexadecimal compare did we determine that the file was all there, just not in the same order as the original.
Any thoughts on what might be causing the blocks of data to be reordered?
P.S. I know the HttpClient is not being used as effectively as possible.
After some long and tedious testing (Yay, scientific method) we determined that our web content filter software was causing the issue.
I am developing client-server application. The server side is asp.net web api. I did simple web api application and simple android client. When I set up web api it works. And I get json. But how I can get data from my clietn application? I conncted my Android-device and trying to get data via WI-FI from my web api. For web api I create a seld hosting.
protected Boolean doInBackground(String... urls) {
BufferedReader in = null;
try {
HttpClient client = new DefaultHttpClient();
HttpGet request = new HttpGet("http://124.18.240.169:3890/api/values/1/");
HttpResponse response = client.execute(request);
in = new BufferedReader(
new InputStreamReader(
response.getEntity().getContent()));
StringBuffer sb = new StringBuffer("");
String line = "";
String NL = System.getProperty("line.separator");
while ((line = in.readLine()) != null) {
sb.append(line + NL);
}
in.close();
String page = sb.toString();
System.out.println(page);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return true;
}
It is my web api
static void Main(string[] args)
{
var config = new HttpSelfHostConfiguration("http://124.18.240.169:3890");
config.Routes.MapHttpRoute(
"API Default", "api/{controller}/{id}",
new { id = RouteParameter.Optional });
using (HttpSelfHostServer server = new HttpSelfHostServer(config))
{
server.OpenAsync().Wait();
Console.WriteLine("Press Enter to quit.");
Console.ReadLine();
}
}
where
124.18.240.160 is my IP whcih i found in ipconfig. What I should to do (I tried to do like
http://localhost) but it not wrok for Android app
You should consider using a library to help handle async callbacks. It can be super helpful for this.
This is the one I usually use:
LoopJ's Async HTTP Callback Library
This will handle GET and POST requests with a lot of cool features such as custom timeouts, JSON format, onSuccess() and onFailure() methods, etc. There's a lot of working examples of this library too. I've used it in all my apps and haven't had any problems yet!
Hopefully this helps.
I am trying to trigger a create action in my ASP.NET web application from android.
The code seems to be working fine with no errors. I am using IIS 6 in Windows 7. I suspect a missing configuration in IIS?
I didn't get value in the web app.
Android Code:
List<NameValuePair> postParameters = new ArrayList<NameValuePair>();
postParameters.add(new BasicNameValuePair("supplier_name",
"Thein Htike Aung"));
HttpClient client1 = new DefaultHttpClient();
HttpPost request =
new HttpPost("http://192.168.1.104/LogicUniversity/SupplierHandler.ashx");
try {
UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(postParameters);
request.setEntity(formEntity);
request.addHeader("Content-type", "application/x-www-form-urlencoded");
HttpResponse response = client1.execute(request);
BufferedReader in = new BufferedReader(
new InputStreamReader(
response.getEntity().getContent()));
String line;
String page="";
line = in.readLine();
while(line!=null)
{
page=page+line;
line=in.readLine();
}
Log.i("Page",page);
in.close();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
In Web Handler
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using ApplicationLayer.Controllers;
using ApplicationLayer;
namespace PresentationLayer
{
/// <summary>
/// Summary description for SupplierHandler
/// </summary>
public class SupplierHandler : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
string name = context.Request.QueryString["supplier_name"];
if (name != null)
{
Supplier s = new Supplier();
s.supplier_name = name;
s.code = "TEST";
new SupplierController().actionCreateSupplier(s);
}
}
public bool IsReusable
{
get
{
return false;
}
}
}
}
You say that you're using a HTTP POST to push your value(s) to the server yet in your HTTP Handler you're reading from the query string:
string name = context.Request.QueryString["supplier_name"];
This should be:
string name = context.Request.Form["supplier_name"];
192.168.1.104 is specific to your local network. Your HTTPPost request, from the Andriod code, assumes that the Andriod device is on the same local network, is this your intention? This could be one of many causes on why your code work in development, and not production environment. You would need a Static IP configured on your web server to access the web service outside the local network.
I have a console application to download a file from a SharePoint site. The sharepoint site uses claims based authentication.
This code throws a 403 Forbidden exception. The specified Network credential has full access to the site, and is able to download the same file from a browser.
WebClient webClient = new WebClient();
webClient.Credentials = new NetworkCredential(username,Password,domain);
byte[] fileData = webClient.DownloadData(urlOfAFile);
FileStream file = File.Create(localPath);
file.Write(fileData, 0, fileData.Length);
Any idea how to fix this?
Maybe a bit late, but adding the right request header before making the request solves the problem:
webClient.Headers.Add("X-FORMS_BASED_AUTH_ACCEPTED", "f");
I also encounter this issue, and below is my research:
{
ClientContext m_clientContext = new ClientContext(strSiteUrl);
m_clientContext.ExecutingWebRequest += new EventHandler<WebRequestEventArgs>(ctx_MixedAuthRequest);
m_clientContext.AuthenticationMode = ClientAuthenticationMode.Default;
m_clientContext.Credentials = new NetworkCredential(uname, pwd);
Web m_currentWeb = m_clientContext.Web;
m_clientContext.Load(m_currentWeb);
m_clientContext.ExecuteQuery();
}
private void ctx_MixedAuthRequest(object sender, WebRequestEventArgs e)
{
try
{
//Add the header that tells SharePoint to use Windows authentication.
e.WebRequestExecutor.RequestHeaders.Add(
"X-FORMS_BASED_AUTH_ACCEPTED", "f");
}
catch (Exception ex)
{
MessageBox.Show("Error setting authentication header: " + ex.Message);
}
}
here is the article: https://msdn.microsoft.com/en-us/library/office/hh124553(v=office.14).aspx