I am trying to figure out how to post a file to my webservice using servicestack. I have the following code in my client
Dim client As JsonServiceClient = New JsonServiceClient(api)
Dim rootpath As String = Server.MapPath(("~/" + "temp"))
Dim filename As String = (Guid.NewGuid.ToString.Substring(0, 7) + FileUpload1.FileName)
rootpath = (rootpath + ("/" + filename))
FileUpload1.SaveAs(rootpath)
Dim fileToUpload = New FileInfo(rootpath)
Dim document As AddIDVerification = New AddIDVerification
document.CountryOfIssue = ddlCountry.SelectedValue
document.ExpiryDate = DocumentExipiry.SelectedDate
document.VerificationMethod = ddlVerificationMethod.SelectedValue
Dim responseD As MTM.DTO.AddIDVerificationResponse = client.PostFileWithRequest(Of DTO.AddIDVerificationResponse)("http://localhost:50044/images/", fileToUpload, document)
But no matter what I do I get the error message "Method not allowed". At the moment the server code is written like this
Public Class AddIDVerificationService
Implements IService(Of DTO.AddIDVerification)
Public Function Execute(orequest As DTO.AddIDVerification) As Object Implements ServiceStack.ServiceHost.IService(Of DTO.AddIDVerification).Execute
Return New DTO.AddIDVerificationResponse With {.Result = "success"}
End Function
End Class
As you can see I have not tried to process the file on the server yet. I just want to test the client to make sure it can actually send the file to the server. Any ideas what I am doing wrong?
Firstly you're using ServiceStack's Old and now deprecated API, consider moving to ServiceStack's New API for creating future services.
You can look at ServiceStack's RestFiles example project for an example of handling file uploads:
foreach (var uploadedFile in base.RequestContext.Files)
{
var newFilePath = Path.Combine(targetDir.FullName, uploadedFile.FileName);
uploadedFile.SaveTo(newFilePath);
}
Which is able to access the collection of uploaded files by inspecting the injected RequestContext.
An example of uploading a file is contained in the RestFiles integration tests:
var client = new JsonServiceClient(api);
var fileToUpload = new FileInfo(FilesRootDir + "TESTUPLOAD.txt");
var response = restClient.PostFile<FilesResponse>(
"files/Uploads/",fileToUpload,MimeTypes.GetMimeType(fileToUpload.Name));
Related
When trying to use the Formality setting (https://aws.amazon.com/about-aws/whats-new/2022/10/amazon-translate-formality-customization-support-dutch-korean-mexican-spanish/ ) in code behind (.Net), I keep getting System.NullReferenceException: 'Object reference not set to an instance of an object.'
Here's the code I'm running - everything works as expected until I add in request.Settings.Formality = "FORMAL";`
using (var client = new AmazonTranslateClient(awsCredentials, selectedRegion))
{
var request = new Amazon.Translate.Model.TranslateTextRequest();
request.Text = toTranslate;
request.SourceLanguageCode = sourceLanguage;
request.TargetLanguageCode = translateLanguage;
request.Settings.Formality = "FORMAL";
`Looking at the limited examples in other languages from the AWS documentation doesn't indicate anything else that's needed. I also tried the Profanity setting and the same results - System.NullReferenceException.
I also tried making the call later via the using statement that looks like this with the same error:`
var response = client.TranslateTextAsync(request).GetAwaiter().GetResult();
response.AppliedSettings.Formality = translationFormality;
`
Updated code with solution that worked for me:
using (var client = new AmazonTranslateClient(awsCredentials, selectedRegion))
{
var request = new Amazon.Translate.Model.TranslateTextRequest();
request.Text = toTranslate;
request.SourceLanguageCode = sourceLanguage; // SourceLanguageItem.LanguageCode;
request.TargetLanguageCode = translateLanguage; // TranslateLanguageItem.LanguageCode;
TranslationSettings settings = new TranslationSettings();
settings.Formality = "FORMAL";
request.Settings = settings;
Look at below c# code as I running this code on the Local server it's working but after deploying in Azure it's not working.
Someone, please help me to resolve this issue
public async Task<IHttpActionResult> ptoexport()
{
string file = #"filepath";
FileInfo fileInfo = new FileInfo(file);
ExcelPackage p = new ExcelPackage(fileInfo);
ExcelWorksheet myWorksheet = p.Workbook.Worksheets["Sheet1"];
myWorksheet.Cells[5, 5].Value = 34;
p.Save();
return Ok("Success");
}
I running this code on the Local server it's working but after deploying in Azure it's not working.
As I have tested, I think the file path you provided in code is your local xlsx file path. So when you run in local, the method could find the file, but when it publish to azure it failed.
So, I suggest that you could upload file to KUDU and change the file path.
I upload the xlsx file here and use the following, it works fine.
public async Task<IHttpActionResult> ptoexport()
{
string file = #"D:/home/site/wwwroot/new.xlsx";
FileInfo fileInfo = new FileInfo(file);
ExcelPackage p = new ExcelPackage(fileInfo);
ExcelWorksheet myWorksheet = p.Workbook.Worksheets["Sheet1"];
myWorksheet.Cells[5, 5].Value = 34;
p.Save();
return Ok("Success");
}
Here is a case about why Azure deploy can't find file, you could also refer to it.
I can't use the ServiceStack Client libraries and I've chosen to use the HttpClient PCL library instead. I can do all my Rest calls (and other json calls) without a problem, but I'm now stucked with uploading files.
A snippet of what I am trying to do:
var message = new HttpRequestMessage(restRequest.Method, restRequest.GetResourceUri(BaseUrl));
var content = new MultipartFormDataContent();
foreach (var file in files)
{
byte[] data;
bool success = CxFileStorage.TryReadBinaryFile(file, out data);
if (success)
{
var byteContent = new ByteArrayContent(data);
byteContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
{
FileName = System.IO.Path.GetFileName(file) ,
};
content.Add(byteContent);
}
}
message.Content = content;
Problem is now that I get a null reference exception (status 500) when posting. I doesn't get into the service. I see the call in the filterrequest, but that's it.
So I'm wondering what I do wrong and how I can pinpoint what is going wrong. How can I catch the correct error on the ServiceStack layer?
I'm building a Request/Acknowledge/Poll style REST service with NServiceBus underneath to manage queue processing. I want to give the client a URI to poll for updates.
Therefore I want to return a location header element in my web service as part of the acknowledgement. I can see that it is possible to do this:
return new HttpResult(response, HttpStatusCode.Accepted)
{
Location = base.Request.AbsoluteUri.CombineWith(response.Reference)
}
But for a Url such as: http://localhost:54567/approvals/?message=test, which creates a new message (I know I should probably just use a POST), the location will be returned as: http://localhost:54567/approvals/?message=test/8f0ab1c1a2ca46f8a98b75330fd3ac5c.
The ServiceStack request doesn't expose the Uri fragments, only the AbsouteUri. This means that I need to access the original request. I want this to work regardless of whether this is running in IIS or in a self hosted process. The closest I can come up with is the following, but it seems very clunky:
var reference = Guid.NewGuid().ToString("N");
var response = new ApprovalResponse { Reference = reference };
var httpRequest = ((System.Web.HttpRequest)base.Request.OriginalRequest).Url;
var baseUri = new Uri(String.Concat(httpRequest.Scheme, Uri.SchemeDelimiter, httpRequest.Host, ":", httpRequest.Port));
var uri = new Uri(baseUri, string.Format("/approvals/{0}", reference));
return new HttpResult(response, HttpStatusCode.Accepted)
{
Location = uri.ToString()
};
This now returns: http://localhost:55847/approvals/8f0ab1c1a2ca46f8a98b75330fd3ac5c
Any suggestions? Does this work regardless of how ServiceStack is hosted? I'm a little scared of the System.Web.HttpRequest casting in a self hosted process. Is this code safe?
Reverse Routing
If you're trying to build urls for ServiceStack services you can use the RequestDto.ToGetUrl() and RequestDto.ToAbsoluteUri() to build relative and absolute urls as seen in this earlier question on Reverse Routing. e.g:
[Route("/reqstars/search", "GET")]
[Route("/reqstars/aged/{Age}")]
public class SearchReqstars : IReturn<ReqstarsResponse>
{
public int? Age { get; set; }
}
var relativeUrl = new SearchReqstars { Age = 20 }.ToUrl("GET");
var absoluteUrl = HostContext.Config.WebHostUrl.CombineWith(relativeUrl);
relativeUrl.Print(); //= /reqstars/aged/20
absoluteUrl.Print(); //= http://www.myhost.com/reqstars/aged/20
For creating Urls for other 3rd Party APIs look at the Http Utils wiki for example extension methods that can help, e.g:
var url ="http://api.twitter.com/user_timeline.json?screen_name={0}".Fmt(name);
if (sinceId != null)
url = url.AddQueryParam("since_id", sinceId);
if (maxId != null)
url = url.AddQueryParam("max_id", maxId);
var tweets = url.GetJsonFromUrl()
.FromJson<List<Tweet>>();
You can also use the QueryStringSerializer to serialize a number of different collection types, e.g:
//Typed POCO
var url = "http://example.org/login?" + QueryStringSerializer.SerializeToString(
new Login { Username="mythz", Password="password" });
//Anonymous type
var url = "http://example.org/login?" + QueryStringSerializer.SerializeToString(
new { Username="mythz", Password="password" });
//string Dictionary
var url = "http://example.org/login?" + QueryStringSerializer.SerializeToString(
new Dictionary<string,string> {{"Username","mythz"}, {"Password","password"}});
You can also serialize the built-in NameValueCollection.ToFormUrlEncoded() extension, e.g:
var url = "http://example.org/login?" + new NameValueCollection {
{"Username","mythz"}, {"Password","password"} }.ToFormUrlEncoded();
I see this article explaining how to upload a file using client API's from a fully trusted app.
How to implement such functionality but from javascript?
For example, I have this code in which I have both the local path of the file and the SharePoint doc lib, how do I complete it?
Thanks!
PS: I'm guessing there must be some fully trusted component involved in the client in order to achieve this, otherwise would be a javascript security hole, but which one would be the right one to use in this case against SharePoint?
<script type="text/javascript">
var list;
var filePath;
function ShowUploadDialog() {
// get file path user chooses through a dialog
var fileDialog = document.getElementById("fileDialog");
fileDialog.click();
filePath = fileDialog.value;
// get list
var context = new SP.ClientContext.get_current();
var site = context.get_site();
var web = site.get_rootWeb();
this.collList = web.get_lists();
list = collList.getByTitle("My doc library");
context.load(list);
context.executeQueryAsync(Succeeded, Failed);
}
function Succeeded(sender, args) {
// I HAVE HERE THE list AND THE filePath, HOW CAN UPLOAD THE FILE TO THE LIST?
}
function Failed(sender, args) {
alert('request failed ' + args.get_message() + '\n' + args.get_stackTrace());
}
</script>
UploadCtl solves this.