i need upload any file vedio,image and doc by api from client to server
This code works for me, but for files smaller than 2MB
I can't download files up to 10 , 20MB
I tried to change the code and style
I also converted it to a byte[] and split it into several files, but it didn't work
Please Help
this code for client
uri = new Uri(WebAPIUrl + "setimg/");
try
{
var content = new MultipartFormDataContent();
if(mediafile!=null)
{
var streamContent = new StreamContent(mediafile);
streamContent.Headers.Add("Content-Type", "application/octet-stream");
content.Add(streamContent, "\"img\"", $"\"{mediafile.Name}\"");
}
string json = JsonConvert.SerializeObject(u);
StringContent content1 = new StringContent(json, Encoding.UTF8, "application/json");
content.Add(content1, "value");
bool fin = false;
do
{
fin = true;
var response = await client.PostAsync(uri, content);
if (response.IsSuccessStatusCode)
{
var result = await response.Content.ReadAsStringAsync();
try
{
var Items = JsonConvert.DeserializeObject<List<string>>(result);
return Items;
}
catch
{
}
}
this code for server
public List<string> upload()
{
var httpRequset = HttpContext.Current.Request;
string imageslink = "";
if (httpRequset.Files.Count > 0)
{
foreach (string file in httpRequset.Files)
{
var postedfile = httpRequset.Files[file];
var filename = postedfile.FileName.Split('\\').LastOrDefault().Split('/').LastOrDefault();
// var filepath = HttpContext.Current.Server.MapPath("~/Uploads/" + filename);
imageslink += "D:\\casting\\" + filename + ";";
var filepath = "D:\\casting\\" + filename;
postedfile.SaveAs(filepath);
}
please help
After communicating with a friend
After searching a lot, I found the cause of the problem is the server itself iis
As it gives a default value for the maximum upload limit of 2 megabytes
Solve the problem if the server is on iis
https://stackoverflow.com/a/58566617/8967661
IIS -> web. config :
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.web>
<!-- ~ 2GB -->
<httpRuntime maxRequestLength="2147483647" /> // kbytes
</system.web>
<system.webServer>
<security>
<requestFiltering>
<!-- ~ 4GB -->
<requestLimits maxAllowedContentLength="4294967295" /> // bytes
</requestFiltering>
</security>
</system.webServer>
</configuration>
Related
I am Facing the problems while Uploading the files to the server through API
When I try to upload the Image size 8 Mb to server From Postman. For the first time, I try to upload it shows "The page was not displayed because the request entity is too large". But the strange thing is "When I upload the small size image like 300 Kb it uploads and tries to upload the next image like 8 MB it uploads and After 3 or 5 minutes im getting same error.
My Upload code
[Route("api/[controller]")]
public class UploadImageController : Controller
{
private IHostingEnvironment _environment;
public UploadImageController(IHostingEnvironment environment)
{
_environment = environment;
}
internal void IsExists(string filepath)
{
if (!Directory.Exists(_environment.WebRootPath + "\\media"))
{
Directory.CreateDirectory(_environment.WebRootPath + "\\media");
}
if (!Directory.Exists(_environment.WebRootPath + "\\media\\" + filepath))
{
Directory.CreateDirectory(_environment.WebRootPath + "\\media\\" + filepath);
}
}
internal string GetNewFileName(string filenamestart, string fullname)
{
Char delimiter = '.';
string fileExtension;
string strFileName = string.Empty;
strFileName = DateTime.Now.ToString().
Replace(" ", string.Empty).
Replace("/", "-").Replace(":", "-");
fileExtension = fullname.Split(delimiter).Last();
Random ran = new Random();
strFileName = $"{ filenamestart}_{ran.Next(0, 100)}_{strFileName}.{fileExtension}";
return strFileName;
}
private bool IsValidExtension(IFormFile filename)
{
bool isValid = false;
Char delimiter = '.';
string fileExtension;
string[] imgTypes = new string[] { "png", "jpg", "gif", "jpeg" };
fileExtension = filename.FileName.Split(delimiter).Last();
// fileExtension = substrings[substrings.Length - 1].ToString();
int fileType = 0;
if (imgTypes.Contains(fileExtension.ToLower()))
{
fileType = 1;
}
switch (fileType)
{
case 1:
if (imgTypes.Contains(fileExtension.ToLower()))
{
isValid = true;
}
break;
default:
isValid = false;
break;
}
return isValid;
}
[HttpPost]
// GET: api/<controller>
[Route("UploadapiImage")]
[RequestFormLimits(MultipartBodyLengthLimit = 209715200)]
[RequestSizeLimit(209715200)]
public async Task<IActionResult> UploadapiImage()
{
try
{
var Files=Request.Form.Files;
if (Files.Count == 0)
{
return Ok(Json(""));
}
IsExists("Mobile");
//var file = Convert.FromBase64String(objUploadModel.File);
string uploads = _environment.WebRootPath + "\\media\\Mobile";
int i = 0;
string[] strFileNames = new string[Files.Count];
foreach (var file in Files)
{
if (IsValidExtension(file))
{
string imagename = GetNewFileName("Mobile", Files[i].FileName);
string fullpath = uploads + "\\" + imagename;
using (FileStream fileStream = System.IO.File.Create(fullpath))
{
await Task.Run(() => Files[i].CopyToAsync(fileStream));
fileStream.Flush();
fileStream.Close();
}
strFileNames[i] = "\\media\\Mobile\\" + imagename;
}
else
{
strFileNames[i] = "";
}
i++;
}
return Ok(strFileNames);
}
catch (Exception ex)
{
return Ok("Exception from Api");
}
}
}
In Startup.cs
services.Configure<FormOptions>(x =>
{
x.ValueLengthLimit = int.MaxValue;
x.MultipartHeadersLengthLimit = int.MaxValue;
x.MultipartBodyLengthLimit = int.MaxValue;
});
In Web Config.
<requestFiltering>
<requestLimits maxAllowedContentLength="1073741824" />
</requestFiltering>
I try to keep logs in server and IIS I didn't find any information.
In IIS logs it writes
#Software: Microsoft Internet Information Services 10.0
Version: 1.0
Date: 2019-11-10 05:59:05
Fields: date time s-ip cs-method cs-uri-stem cs-uri-query s-port cs-username c-ip cs(User-Agent) cs(Referer) sc-status sc-substatus sc-win32-status time-taken
2019-11-10 05:59:05 10.0.0.4 POST /api/UploadImage/UploadapiImage - 443 - 27.34.104.230 Mozilla/5.0+(Windows+NT+10.0;+Win64;+x64)+AppleWebKit/537.36+(KHTML,+like+Gecko)+Chrome/78.0.3904.97+Safari/537.36 - 413 0 0 1636
My IIS version in sever is show on Image.
Why I am getting the problem ("The page was not displayed because the request entity is too large")
in my website, SSL Setting is Accept
I just set it to Ignore then it works.
I am creating a universal Windows Phone 8.1 App. I am trying to download the file and view it into launcher. I works for small file less than 15 MB files. But when file size is more than 15 MB, I got the out of memory exception.
async private Task<object> GetMailAttachments(string attachNotify)
{
try
{
cmdBarMailItem.IsEnabled = false;
if (await Device.IsNetworkAvailable())
{
cts = new CancellationTokenSource();
// Ignore SSL Certificate which is untrusted,expired and has invalid hostname.
var filter = new HttpBaseProtocolFilter() { AllowUI = false };
filter.IgnorableServerCertificateErrors.Add(Windows.Security.Cryptography.Certificates.ChainValidationResult.Untrusted);
filter.IgnorableServerCertificateErrors.Add(Windows.Security.Cryptography.Certificates.ChainValidationResult.Expired);
filter.IgnorableServerCertificateErrors.Add(Windows.Security.Cryptography.Certificates.ChainValidationResult.InvalidName);
// Start calling the soap service #userGetAttachmentByIndex
using (var client = new System.Net.Http.HttpClient(new WinRtHttpClientHandler(filter)))
{
//Prepare parameters which is to be post via soap envelope.
List<KeyValuePair<string, string>> parameter = new List<KeyValuePair<string, string>>();
parameter.Add(new KeyValuePair<string, string>("sessionId", GlobalInfo.SessionID));
parameter.Add(new KeyValuePair<string, string>("attachmentIndex", attachNotify.Split('|')[1].ToString()));
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("text/xml"));
client.DefaultRequestHeaders.Add("SOAPAction", "userGetAttachmentByIndex");
var postContent = new StringContent(StringHelper.ConstructSoapRequest(parameter, "userGetAttachmentByIndex"), Encoding.UTF8, "text/xml");
// Getting response from soap service
var response = await client.PostAsync(new Uri(AppEnv.ServiceEndPoint), postContent, cts.Token);
if (response.StatusCode == System.Net.HttpStatusCode.OK)
{
string soapResponse = await response.Content.ReadAsStringAsync();
var soap = XDocument.Parse(soapResponse);
XNamespace ns = "http://service.webservice.cryoserver.ci";
var base64BinaryStr = soap.Descendants(ns + "userGetAttachmentByIndexResponse").First().Descendants(ns + "return").First().Descendants(ns + "attachmentType").First().Descendants(ns + "binaryData").First().Descendants(ns + "base64Binary").First().Value;
await saveStringToLocalFile(base64BinaryStr);
var file = await Windows.Storage.ApplicationData.Current.LocalFolder.GetFileAsync("myTest.pdf");
bool x = await Windows.System.Launcher.LaunchFileAsync(file);
return x;
}
}
}
cmdBarMailItem.IsEnabled = true;
}
catch (TaskCanceledException)
{
PopupRetrieve.IsOpen = false;
ProgressBar.IsVisible = false;
cmdBarMailItem.IsEnabled = true;
}
catch(Exception ex)
{
cmdBarMailItem.IsEnabled = true;
ProgressBar.IsVisible = false;
MessageBox.Show(AlertType.Connectivity);
}
return null;
}
async Task saveStringToLocalFile(string content)
{
try
{
// saves the string 'content' to a file 'filename' in the app's local storage folder
// byte[] fileBytes = System.Text.Encoding.UTF8.GetBytes(content.ToCharArray());
byte[] byteArray = Convert.FromBase64String(content);
// create a file with the given filename in the local folder; replace any existing file with the same name
StorageFile file = await Windows.Storage.ApplicationData.Current.LocalFolder.CreateFileAsync("myTest.pdf", CreationCollisionOption.ReplaceExisting);
// write the char array created from the content string into the file
using (var stream = await file.OpenStreamForWriteAsync())
{
stream.Write(byteArray, 0, byteArray.Length);
stream.Flush();
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
I got the exception on executing the line
string soapResponse = await response.Content.ReadAsStringAsync();
Anybody have an idea why the exception occurs ? What could be possible solution to fix it.
Any help would be appriciable. :)
My application changes end-point settings at run-time and persists the changes to config file. But when I create a new service proxy instance, the end-point settings are the ones that were before the update. How do I force the proxy to get new settings?
You will need to detect if your configuration file has been updated be it your main app.config / web.config or any external configuration file you are using via configSource.
If a change is detected you will need to refresh the system.serviceModel configuration section:
ConfigurationManager.RefreshSection("system.serviceModel/client");
Existing Channels and ChannelFactories will not pick up the changes so they will need to be closed and new ones created.
The following example shows this in action:
[TestFixture]
class When_trying_to_change_service_endpoints_on_the_fly
{
[Test]
public void Should_use_the_new_endpoint()
{
var someService1 = Substitute.For<ISomeWebService>();
var someService2 = Substitute.For<ISomeWebService>();
var serviceHost1 = CreateServiceHost(someService1, new Uri("http://localhost:50001"));
var serviceHost2 = CreateServiceHost(someService2, new Uri("http://localhost:50002"));
serviceHost1.Open();
serviceHost2.Open();
UpdateEndpointInConfig(new Uri("http://localhost:50001"));
var channelFactory = new ChannelFactory<ISomeWebService>("TestReloadConfig");
var channel1 = channelFactory.CreateChannel();
channel1.ServiceMethod();
((IChannel)channel1).Close();
channelFactory.Close();
UpdateEndpointInConfig(new Uri("http://localhost:50002"));
channelFactory = new ChannelFactory<ISomeWebService>("TestReloadConfig");
var channel2 = channelFactory.CreateChannel();
channel2.ServiceMethod();
((IChannel)channel2).Close();
serviceHost1.Close();
serviceHost2.Close();
someService1.Received(1).ServiceMethod();
someService2.Received(1).ServiceMethod();
}
private static void UpdateEndpointInConfig(Uri endpointAddress)
{
var configFile = new ExeConfigurationFileMap();
configFile.ExeConfigFilename = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None).FilePath;
var config = ConfigurationManager.OpenMappedExeConfiguration(configFile, ConfigurationUserLevel.None);
var serviceModelConfig = (ServiceModelSectionGroup) config.GetSectionGroup("system.serviceModel");
serviceModelConfig.Client.Endpoints[0].Address = endpointAddress;
config.Save();
ConfigurationManager.RefreshSection("system.serviceModel/client");
}
private ServiceHost CreateServiceHost<TService>(TService service, Uri baseUri)
{
var serviceHost = new ServiceHost(service, new Uri[0]);
serviceHost.Description.Behaviors.Find<ServiceDebugBehavior>().IncludeExceptionDetailInFaults = true;
serviceHost.Description.Behaviors.Find<ServiceBehaviorAttribute>().InstanceContextMode = InstanceContextMode.Single;
serviceHost.AddServiceEndpoint(typeof(TService), new BasicHttpBinding(), baseUri);
return serviceHost;
}
}
[ServiceContract]
public interface ISomeWebService
{
[OperationContract]
void ServiceMethod();
}
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<client>
<endpoint address="http://localhost:50000" binding="basicHttpBinding" contract="Junk.ISomeWebService" name="TestReloadConfig" />
</client>
</system.serviceModel>
</configuration>
If you managed the endpoint configurations another way you could update any ChannelFactory instance manually as you have access to the Endpoint and Binding properties.
var store = new DocumentStore()
{
Url = #"http://localhost"
};
store.Initialize();
Blog blog = new Blog()
{
Title = "Hello RavenDB",
Category = "RavenDB",
Content = "This is a blog about RavenDB",
Comments = new BlogComment[]{
new BlogComment() { Title = "Unrealistic", Content= "This example is unrealistic"},
new BlogComment() { Title = "Nice", Content= "This example is nice"}
}
};
using (IDocumentSession session = store.OpenSession())
{
session.Store(blog);
session.SaveChanges();
}
The above code saves data to the default database. (It is a web application.) But I want it save data to another database that I created the raven management studio (web page). Where do i specify the database name? Also please tell me how I can save the connection string with the database name in the config file. This is how I would save it to config file without the database name
<connectionStrings>
<add name="Local" connectionString="DataDir = ~\Data"/>
<add name="Server" connectionString="Url = http://localhost:8080"/>
</connectionStrings>
All of your questions are explained in the documentation:
new DocumentStore
{
ConnectionStringName = "Local"
}
<connectionStrings>
<add name="Local" connectionString="DataDir=~\Data;Database=MyDatabaseName"/>
<add name="Server" connectionString="Url=http://localhost:8080;Database=MyDatabaseName"/>
</connectionStrings>
The other answers are ok, but for efficiency you really only want one instance of DocumentStore for your application, unless you are running multiple Raven servers and then it would be acceptable to have one per server.
If you are just connecting to different databases on the same server, you should use:
var store = new DocumentStore(...your connection string or inline options...);
using (var session = store.OpenSession("the database name")
{
...
}
You can keep your connection strings data as you shown, best with the databases names at the end:
<connectionStrings>
<add name="Core" connectionString="Url=http://localhost:8082/databases/Core"
providerName="My primary database." />
<add name="Backup" connectionString="Url=http://localhost:8082/databases/Backup"
providerName="My backup stuff." />
</connectionStrings>
Next you can implement singleton class which will keep all your handlers for defined sources, for example:
public class DocumentStoreProvider : IDocumentStoreProvider
{
private static readonly IDictionary<string, IDocumentStore> _documentStores = new Dictionary<string, IDocumentStore>();
private static readonly DocumentStoreProvider _instance = new DocumentStoreProvider();
private DocumentStoreProvider()
{
var connectionStrings = ConfigurationManager.ConnectionStrings;
foreach (ConnectionStringSettings connectionString in connectionStrings)
{
var name = connectionString.Name;
var connection = connectionString.ConnectionString;
IDocumentStore currentStore = new DocumentStore { ConnectionStringName = name };
currentStore.Initialize();
currentStore.DatabaseCommands.EnsureDatabaseExists(name);
IndexCreation.CreateIndexes(Assembly.Load("Your.Assembly.Containing.Indexes"), currentStore);
_documentStores.Add(name, currentStore);
}
}
public static DocumentStoreProvider Instance
{
get { return _instance; }
}
public IDocumentStore GetDocumentStore(string key)
{
return _documentStores[key];
}
}
The usage can be following:
using (var session = DocumentStoreProvider.Instance.GetDocumentStore("Backup").OpenSession())
{
/* do stuff for chosen database... */
session.Store(something);
session.SaveChanges();
}
I have WCF service library with this config:
<basicHttpBinding>
<binding name="httpLargeMessageStream"
maxReceivedMessageSize="2147483647"
messageEncoding="Mtom" transferMode="Streamed" />
</basicHttpBinding>
<netTcpBinding>
<binding name="tcpLargeMessageStream" transferMode="Streamed"
maxReceivedMessageSize="2147483647" />
</netTcpBinding>
and from client side if I send request for upload file, then all work fine
public void UploadFile(FileUploadMessage request)
{
try
{
// Gets absolute local storing path
string localPath = Path.Combine(basePath, request.UploadMetadata.StoringPath);
// Create folders in they don't exist
FileInfo file = new System.IO.FileInfo(localPath);
file.Directory.Create();
// Get document path on server
string serverFileName = Path.Combine(localPath, request.UploadMetadata.HashFileName);
// Create a new temp document
using (FileStream outfile = new FileStream(serverFileName, FileMode.Create))
{
// Read buffer
const int bufferSize = 65536;
// Output buffer
Byte[] buffer = new Byte[bufferSize];
int bytesRead;
// Write bytes from source into local file
while ((bytesRead = request.FileByteStream.Read(buffer, 0, bufferSize)) > 0)
{
outfile.Write(buffer, 0, bytesRead);
}
}
}
catch (IOException e)
{
throw new FaultException<IOException>(e);
}
}
but for download request I already got error:
The maximum message size quota for
incoming messages (65536) has been
exceeded. To increase the quota, use
the MaxReceivedMessageSize property on
the appropriate binding element.
public FileDownloadReturnMessage DownloadFile(FileDownloadMessage request)
{
try
{
controlServerAdress = "http://localhost:8080/ControlServer/";
EndpointAddress basicBinding = new EndpointAddress(controlServerAdress + "TokenService/basic");
tokenService = new TokenServiceClient("BasicHttpBinding_ITokenService", basicBinding);
// Get file token form control server
ComDocFile file = tokenService.ResolveToken(request.DownloadMetadata.Token);
// If exist file for token
if (file != null)
{
// Get document path on server
string serverFileName = Path.Combine(basePath, file.FilePath, file.FileName);
// Set fileName
request.DownloadMetadata.FileName = file.FileName;
// Return file stream
return new FileDownloadReturnMessage(new FileStream(serverFileName, FileMode.Open, FileAccess.Read), new ReturnDownloadMetaData(file.FileName, true));
}
return new FileDownloadReturnMessage(null,
new ReturnDownloadMetaData(null, false));
}
catch (IOException e)
{
throw new FaultException<IOException>(e);
}
}
Client calling method:
// Read buffer
const int bufferSize = 65536;
// Output buffer
Byte[] buffer = new Byte[bufferSize];
int bytesRead;
// Prepare download stream
Stream donwloadStream;
ReturnDownloadMetaData file = fileClient.DownloadFile(downloadMetaData, out donwloadStream);
// If file server return valid file stream
if (file.IsValid)
{
// Create a new temp document
using (FileStream outfile = new FileStream("C:\\#ComDocs_FileServer\\" + file.FileName, FileMode.Create))
{
// Write bytes from source into local file
while ((bytesRead = donwloadStream.Read(buffer, 0, bufferSize)) > 0)
{
outfile.Write(buffer, 0, bytesRead);
}
}
}
the maxReceievedMessageSize is how big the data is that the receiver is prepared to accept. In the code above, for download, the client is the receiver. You need to increase the maxReceievedMessageSize in the client as well (you don't appear to be doing this from the code you have shown)
Use this
maxBufferSize ="2147483647" maxReceivedMessageSize="2147483647"
at both sender and receiver end.