I have created an application in which i have successfully write the details in the file. But while accessing the file from the application i am getting the following exceptoin:
Following is my class:
public class UserDetails
{
public string Name { get; set; }
public string Course { get; set; }
public string City { get; set; }
}
Following is my code to write and read and file:
private async void btnSearch_Click(object sender, RoutedEventArgs e)
{
details.Name = TxtName.Text;
details.Course = TxtCouse.Text;
details.City = TxtCity.Text;
await SaveAsync();
this.Frame.Navigate(typeof(string));
}
private async Task SaveAsync()
{
StorageFolder localfolder = await ApplicationData.Current.LocalFolder.CreateFolderAsync("Storage Application", CreationCollisionOption.OpenIfExists);
StorageFile sampleFile = await localfolder.CreateFileAsync("UserDetails", CreationCollisionOption.ReplaceExisting);
IRandomAccessStream stream = await sampleFile.OpenAsync(FileAccessMode.ReadWrite);
using(IOutputStream outstream = stream.GetOutputStreamAt(0))
{
DataContractSerializer serializer = new DataContractSerializer(typeof(UserDetails));
serializer.WriteObject(outstream.AsStreamForWrite(), details);
await outstream.FlushAsync();
}
await RestoreDataAsync();
}
private async Task RestoreDataAsync()
{
StorageFolder localfolder = await ApplicationData.Current.LocalFolder.GetFolderAsync("Storage Application");
StorageFile sampleFile = await localfolder.GetFileAsync("UserDetails");
IRandomAccessStream inStream = await sampleFile.OpenAsync(FileAccessMode.Read);
DataContractSerializer serializer = new DataContractSerializer(typeof(UserDetails));
var Details = (UserDetails)serializer.ReadObject(inStream.AsStreamForRead());
inStream.Dispose();
TblName.Text = details.Name;
TblCourse.Text = details.Course;
TblCity.Text = details.City;
}
I am new in creating Windows Store App.
The issue is your SaveAsync() method, You opened the StorageFile of sampleFile, but havn't disposed it. Try to add sampleFile.Dispose(); after you used it.
Related
This is my model class
public class ImageModel
{
[Key]
public int ImageId { get; set; }
[Column(TypeName = "nvarchar(50)")]
public string Title { get; set; }
[Column(TypeName = "nvarchar(100)")]
[DisplayName("Image Name")]
public string ImageName { get; set; }
[NotMapped]
[DisplayName("Upload File")]
public IFormFile ImageFile { get; set; }
}
This is my controller class for post request
And I create a wwwroot folder to save Image
[Route("api/[Controller]")]
[ApiController]
public class ImageController : Controller
{
private readonly Databasecontext _context;
private readonly IWebHostEnvironment _hostEnvironment;
public ImageController(Databasecontext context, IWebHostEnvironment hostEnvironment)
{
_context = context;
this._hostEnvironment = hostEnvironment;
}
// GET: Image
public async Task<IActionResult> Index()
{
return View(await _context.Images.ToListAsync());
}
// GET: Image/Create
public IActionResult Create()
{
return View();
}
// POST: Image/Create
[HttpPost]
public async Task<IActionResult> Create([Bind("ImageId,Title,ImageName")] ImageModel imageModel)
{
if (ModelState.IsValid)
{
//Save image to wwwroot/image
string wwwRootPath = _hostEnvironment.WebRootPath;
string fileName = Path.GetFileNameWithoutExtension(imageModel.ImageFile.FileName);
string extension = Path.GetExtension(imageModel.ImageFile.FileName);
imageModel.ImageName = fileName = fileName + DateTime.Now.ToString("yymmssfff") + extension;
string path = Path.Combine(wwwRootPath + "/Image/", fileName);
using (var fileStream = new FileStream(path, FileMode.Create))
{
await imageModel.ImageFile.CopyToAsync(fileStream);
}
//Insert record
_context.Add(imageModel);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
return View(imageModel);
}
This is my DB context
public DbSet<ImageModel> Images { get; set; }
I just need to test this using postman and combine it with angular. Can someone help me?
when I send an image through postman I get this error The request entity has a media type that doesn't support server or resource does not support.
That is because you use [ApiController] in your controller, it allows data from body by default. So you need specific the source by using [FromForm] attribute like below:
[HttpPost]
public async Task<IActionResult> Create([Bind("ImageId,Title,ImageName")][FromForm] ImageModel imageModel)
{
//..
return View(imageModel);
}
Besides, if you use [Bind("ImageId,Title,ImageName")], ImageFile cannot be binded to the model.
Sorry for my Spanish in the code.
This is how i upload the file in Base64 and then copy the file to a Directory.
I Pupulate the Object ArchivoAnexoUploadDto using a page http://base64.guru/converter/encode/file for convert a file to a base64.
I Hope tha this extract of the code will be usefull for you
1 - Controller
[HttpPost("UploadFileList")]
public async Task<IActionResult> UploadFileList(List<ArchivoAnexoUploadDto> fileList)
{
IOperationResult<object> operationResult = null;
try
{
operationResult = await _fileService.UploadFileList(fileList);
if (!operationResult.Success)
{
return BadRequest(operationResult.ErrorMessage);
}
return Ok(operationResult.Entity);
}
catch (Exception ex)
{
return BadRequest(operationResult.Entity);
}
}
I Recibe a List of Objects < ArchivoAnexoUploadDto > and the service converts the base 64 to Bytes array.
2 - Service
public async Task<IOperationResult<object>> UploadFileList(List<ArchivoAnexoUploadDto> files)
{
List<ArchivoAnexoCreateDto> fileList = PrepareFileList(files);
Response result = ValidateFiles(fileList);
if (!result.Status)
{
Response responseError = new()
{
Status = false,
Message = ((FormFile)result.Object).FileName,
MessageDetail = result.Message
};
return OperationResult<object>.Ok(responseError);
}
var saveResult = await SaveFileList(fileList);
Response respuesta = new()
{
Status = true,
Message = "Los archivos fueron almacenados exitosamente.",
MessageDetail = ""
};
return OperationResult<object>.Ok(respuesta);
}
private List<ArchivoAnexoCreateDto> PrepareFileList(List<ArchivoAnexoUploadDto> files)
{
List<ArchivoAnexoCreateDto> formFileList = new List<ArchivoAnexoCreateDto>();
foreach (ArchivoAnexoUploadDto newFile in files)
{
byte[] fileBytes = Convert.FromBase64String(newFile.Base64);
string filePath = Path.Combine(_fileSettings.PrincipalPath, _fileSettings.PrincipalFolderName, newFile.NombreArchivo);
MemoryStream memoryStream = new MemoryStream();
memoryStream.Write(fileBytes, 0, fileBytes.Length);
FormFile fileData = new FormFile(memoryStream, 0, memoryStream.Length, newFile.NombreArchivo, newFile.NombreArchivo);
ArchivoAnexoCreateDto fileDto = new()
{
FileId = 0,
Data = fileData,
FileName = newFile.NombreArchivo,
Module = newFile.Modulo
};
formFileList.Add(fileDto);
}
return formFileList;
}
private Response ValidateFiles(List<ArchivoAnexoCreateDto> fileList)
{
foreach (ArchivoAnexoCreateDto fileObj in fileList)
{
IFormFile file = fileObj.Data;
try
{
ValidateFile(file);
}
catch (Exception exception)
{
return new Response { Status = false, Message = exception.Message, Object = file };
}
}
return new Response { Status = true, Message = "" };
}
The Service recibe the Array and PrepareFileList return the same data but the array have IFormFile instead of Base64 string.
3 - Dtos
public sealed class ArchivoAnexoUploadDto
{
public long AnexoFileId { get; set; }
public string Base64 { get; set; }
public string NombreArchivo { get; set; }
public Module Modulo {get; set;}
}
public sealed class ArchivoAnexoCreateDto
{
public long FileId { get; set; }
public IFormFile Data { get; set; }
public int FileTypeId { get; set; }
public string FileName { get; set; }
public Module Module { get; set; }
}
ArchivoAnexoUploadDto Is the Dto that recives the base64 and the name of the file.
ArchivoAnexoCreateDto Is the Dto with IFormFile property and is used to copy the file to a Directory.
4 - Validate IFormFile To Copy to Dir
private void ValidateFile(IFormFile fileToCreate)
{
if (fileToCreate == null)
{
throw new Exception("No ha enviado ningun archivo.");
}
IOperationResult<string> fileExtensionResult = _fileService.GetFileExtension(fileToCreate);
if (!fileExtensionResult.Success)
{
throw new Exception(fileExtensionResult.ErrorMessage);
}
if (!_fileSettings.AllowedExtensions.Contains(fileExtensionResult.Entity))
{
throw new Exception("La extención del archivo no es permitida.");
}
IOperationResult<long> fileSizeResult = _fileService.GetFileSize(fileToCreate);
if (!fileSizeResult.Success)
{
throw new Exception("Ha ocurrido un error obteniendo el tamaño del archivo.");
}
if (fileSizeResult.Entity > _fileSettings.MaxFileSize)
{
throw new Exception("El tamaño del archivo supera el limite.");
}
}
This are Conditions for validate (Only for explain) I Did this stuff because the business configured a list of extensions, a size limit of the files, etc.
Hi I have a Login API which I am using to login though my xamarin.forms app.
I will post my username and password and in return I am getting some data.Now Iam facing some issues at deserialization of json. Iam getting data at my resultJson but I cant deserialize it. Help me.
My Json :
[
{
"Result":true,
"ID":"fc938df0",
"LoginName":"test",
"UserName":"test",
"ConnectionString":"MSSQLSERVER;Initial Catalog=Test1;User ID=db;Password=db#2018",
"UserProfileID":"fc938df0"
}
]
My API Call class which have deserialization of Json.
public T APICallResult<T>()
{
try
{
Device.BeginInvokeOnMainThread(() =>
{
if (loadingIndicator != null)
{
loadingIndicator.IsRunning = true;
loadingIndicator.IsVisible = true;
}
});
var client = new HttpClient { BaseAddress = baseAddress };
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var req = new HttpRequestMessage(HttpMethod.Post, apiurl);
req.Content = new StringContent(postdata, Encoding.UTF8, "application/json");
string stringObtained = "";
Task<string> task = Task.Run(async () => await Threading(client, req));
task.Wait();
stringObtained = task.Result;
var jsonObtained = Regex.Unescape(stringObtained);
int startIndex = jsonObtained.IndexOf('[');
int endIndex = jsonObtained.LastIndexOf(']');
int length = endIndex - startIndex + 1;
var resultJSON = jsonObtained.Substring(startIndex, length);
T resultObject;//Generic type object
try
{
//**Deserializing**
resultObject = JsonConvert.DeserializeObject<T>(resultJSON);//, settings);
removeLoadingAnimation();
return resultObject;
}
catch (Exception e)
{
List<ErrorMessageData> errorMessages = JsonConvert.DeserializeObject<List<ErrorMessageData>>(resultJSON);
errorMessage = errorMessages[0];
removeLoadingAnimation();
return default(T);
}
}
catch (Exception e)
{
errorMessage = new ErrorMessageData();
errorMessage.Flag = false;
errorMessage.Message = e.Message;
removeLoadingAnimation();
return default(T);
}
}
My API call at login class
string postdataForLogin = "{\"userName\":\"" + userName.Text + "\",\"password\":\"" + password.Text + "\",\"RequestURL\":\"" + CommonValues.RequestURL + "\"}";
APICall callForLogin = new APICall("/API/LoginMobile/HomeLogin", postdataForLogin, loadingIndicator);
try
{
List<LoginData> resultObjForLogin = callForLogin.APICallResult <List<LoginData>>();
if (resultObjForLogin != null)
{
LoginData loginData = new LoginData();
loginData = resultObjForLogin[0];
Settings.userID = loginData.UserProfileID;
Settings.connectionString = loginData.ConnectionString;
if (loginData.Result)
{
Device.BeginInvokeOnMainThread(async () =>
{
Navigation.InsertPageBefore(new MainPage(), this);
await Navigation.PopAsync();
});
}
My DataModel
public class LoginData
{
public bool Result { get; set; }
public string ID { get; set; }
public string UserProfileID { get; set; }
public string LoginName { get; set; }
public string UserName { get; set; }
public string ConnectionString { get; set; }
}
Its seems strange, My problem solved after downgrading my xamarin.forms from latest version to pre release 4.0.0.169046- pre5. I think its a xamarin forms bug
I have my code, where i fetch data from a url and parse that data with json.
public async void GetItems()
{
HttpResponseMessage response = new HttpResponseMessage();
HttpClient httpclient = new HttpClient();
Uri uri = new Uri("URL");
response = await httpclient.GetAsync(uri);
if (response.IsSuccessStatusCode)
{
var JsonContent = await response.Content.ReadAsStringAsync();
JArray jArray = JArray.Parse(JsonContent);
foreach (var data in jArray)
{
var latitude = data["latitude"];
Console.WriteLine(latitude);
}
}
}
in this code I get all my data and print them into the console.
I have a class with the variables i want to set
public class FetchedObjects
{
public string name { get; set; }
public double latitude { get; set; }
public double longitude { get; set; }
}
How can I store each data from my jArray into these variables? I want to have access to these from my ios or android project.
EDIT
I have some values in json, which are null. How can i handle these, while creating the list? My App crashes, it says :
Error setting value to 'valuename' on 'App.FetchedObjects'
Try it code:
List<FetchedObjects> list = jArray.ToObject<List<FetchedObjects>>();
Edit
in pcl library create class:
public class YourClass
{
public async Task<List<FetchedObjects>> GetItems()
{
....
if(jArray != null)
{
List<FetchedObjects> list = jArray.ToObject<List<FetchedObjects>>();
return list;
}
else
{
return null;
}
...
}
Add reference to pcl library in your ios and android projects and Use class YourClass
I want to send JSON from desktop application to the server with mvc wepApi.
this is my desktop application code ,that convert data to the JSON and send it.
private void btnAddUserType_Click(object sender, EventArgs e)
{
UserType userType = new UserType();
userType.UserTypeName = txtUserTypeName.Text;
string json = JsonConvert.SerializeObject(userType);
HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create("http://localhost:3852/api/default1");
httpWebRequest.ContentType = "text/json";
httpWebRequest.Method = "POST";
var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream());
streamWriter.Write(json);
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
var streamReader = new StreamReader(httpResponse.GetResponseStream());
var responseText = streamReader.ReadToEnd();
}
and this is my web api
// POST api/default1
public void Post([FromBody]string value)
{
UserTypeRepository bl = new UserTypeRepository();
DataContractJsonSerializer js = new DataContractJsonSerializer(typeof(UserType));
MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(value));
UserType u = new UserType();
u = (UserType)js.ReadObject(stream);
bl.Add(u);
}
but when post api is calling the Value is null.
why?
using(var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
streamWriter.Write(json);
You are not flushing nor closing the stream, so basically the data never gets to the api.
My code:
Program.cs - Console App
class Program
{
static void Main(string[] args)
{
var user = new UserModel {Id = 4, FirstName = "Michael", LastName = "Angelo"};
var json = JsonConvert.SerializeObject(user);
HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create("http://localhost:56506/api/Values/");
httpWebRequest.ContentType = "application/json";
httpWebRequest.Method = "POST";
using(var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
streamWriter.Write(json);
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
var streamReader = new StreamReader(httpResponse.GetResponseStream());
var responseText = streamReader.ReadToEnd();
Console.WriteLine(responseText);
Console.ReadKey();
}
}
UserModel.cs - some data class
public class UserModel
{
public string FirstName { get; set; }
public string LastName { get; set; }
public int Id { get; set; }
}
ValuesController.cs - WebApi controller from template
public class ValuesController : ApiController
{
// GET api/values
public UserModel[] Get()
{
return UserProvider.Instance.Get(); // returns some test data
}
// GET api/values/5
public UserModel Get(int id)
{
return new UserModel{Id=1,FirstName="John",LastName="Smith"};
}
// POST api/values
public void Post([FromBody]UserModel value)
{
if (value == null) // BREAKPOINT HERE, just to see what's in value
{
var x = value;
}
}
}
WebApiConfig.cs - default config with added line about Json, but IT WORKS WITHOUT IT -it's so that I can test GET easily in browser etc. ;)
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
// Web API routes
config.MapHttpAttributeRoutes();
config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
Result:
{"names":["name1","name2","name3","name4"]}
I need to fetch this and show them in a list. What I am doing is
public class brand
{ public string Name
{ get; set; }
}
public class brands
{ public list<brand> Names
{ get; set; }
}
public partial class MainPage : PhoneApplicationPage
{
// Constructor
public MainPage()
{
InitializeComponent();
getdata();
}
private void getdata()
{
string uri = "URL";
HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(new Uri(uri));
req.BeginGetResponse(new AsyncCallback(show), req);
}
private void show(IAsyncResult asynchronousResult)
{
HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState;
HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asynchronousResult);
StreamReader stream1 = new StreamReader(response.GetResponseStream());
string s1 = stream1.ReadToEnd();
var ser = new DataContractJsonSerializer(typeof(brands));
var stream = new MemoryStream(Encoding.Unicode.GetBytes(s1));
var bb = (brands)ser.ReadObject(stream);
foreach (var ev in bb.Names)
{
textBlock1.Text = ev.Name.ToString();
}
}
This I made after reading blog posts. I am getting NullReferenceException.
Please tell me where I am doing wrong or alternative way to do the same.
First learn how to parse your JSON data. Consider this as a json string.
String jsonData = #"{""names"":[""name1"",""name2"",""name3"",""name4""]}";
var brands = JsonConvert.DeserializeObject<Brands>(jsonData);
foreach (var item in brands.names)
{
Console.WriteLine(item);
}
Where your Brands class is like this
public class Brands
{
public List<string> names { get; set; }
}
This above code explains how to parse your json data. Now, coming to fetching your json data from web service, as your request is not a POST request (it appears to be get from your code), you can use a simple WebCleint.
void getData()
{
WebClient webClient = new WebClient();
webClient.DownloadStringCompleted += new DownloadStringCompletedEventHandler(webClient_DownloadStringCompleted);
webClient.DownloadStringAsync(new Uri("url"));
}
void wc_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
var brands = JsonConvert.DeserializeObject<Brands>(e.Result);
foreach (var item in brands.names)
{
Console.WriteLine(item);
}
}
Check this blog for any other doubts : Parsing JSON in a Windows Phone Application