How to upload file with model with ASP.NET Core 1.0? - asp.net-core-1.0

I'm trying to make a small upload file api by using ASP.NET Core 1.0.
I have a model which I took from an MVC5 application:
public class RoomModel
{
public int Id { get; set; }
public string Name { get; set; }
public HttpPostedFileBase Image { get; set; }
}
I want to make a function like :
[HttpPost("upload")]
public IActionResult Upload(List<RoomModel> rooms)
{
// Check and upload file here.
// Save parameter to database.
}
In my MVC5, it is OK with HttpPostedFileBase , but in ASP.NET Core, I don't know how to archive with the same result.
Can anyone help me please ?
Thank you.
P/S: I've searched for tutorials like this but found nothing. Every tutorial I've read is only about get key-value parameters , no tutorial is about placing information in a model like this .

Finally, I've found this post :
http://www.mikesdotnetting.com/article/288/uploading-files-with-asp-net-core-1-0-mvc
From this post, my RoomModel will be like this :
public class RoomModel
{
public int Id { get; set; }
public string Name { get; set; }
public IFormFile Image { get; set; }
}
So, as my current knowledge, IFromFile replaces HttpPostedFileBase, and the step handling files is the same as HttpPostedFileBase.

Related

Custom Azure API Apps for Files

I'm looking to create some custom API apps for the sole purpose of creating a/some Logic Apps. With these custom API Apps, I want to pass around files. These files will usually be CSV, ZIP, Excel, TXT, and some other formats - unknown to the consumer until the file is returned (i.e. the client does not dictate the file format).
How does one do something like this in a way that's compatible with Swagger/Swashbuckle, Web API, and Logic Apps? I'll ultimately be tying this into an FTP connector, Dropbox, Onebox, or other file-storage connector.
Does following something like this work or do I need to take a different approach? For example, should I simply work with JSON objects and let my binary be base64-encoded by using a model like this?
public class BinaryFile
{
public string FileName { get; set; }
public string FileExtension { get; set; }
public string DeducedMimeType { get; set; }
public int FileSize { get; set; }
public string FileEncoding { get; set; }
public byte[] FileBinary { get; set; }
}
(this question is cross-posted to MSDN Forums)
The approach I've taken is what I posed in the question with the BinaryFile class. I've broken it out into a few classes. I'm not done - I have some improvements to make still but this is functional right now.
Main class with some common fields:
public class FileResult<T>
{
public string Source { get; set; }
public T File { get; set; }
public IList<string> ErrorMessages { get; set; } = new List<string>();
public bool IsSuccessful { get; set; } = false;
}
This is the <T> in my FileResult<T> class:
public class CsvFile
{
public string Filename { get; set; }
public string Contents { get; set; }
public int Size { get; set; }
}
public class BinaryFile
{
public string FileName { get; set; }
public string FileExtension { get; set; }
public string DeducedMimeType { get; set; }
public int Size { get; set; }
public byte[] Contents { get; set; }
}
Note that in my case, there are some times when I am working with multiple files and not just one, so what could appear to be some common fields are still within the type passed in as the <T> so I can have something like FileResult<IEnumerable<CsvFile>>.
This is all playing nicely with Swagger, Swashbuckle, Web API, Azure API Apps, and Azure Logic Apps. For the cases where I am returning multiple files to my Azure Logic App, I use the fairly hidden splitsOn feature (that also has some designer bugs, so be careful!) to easily iterate over all of the files. It works very nicely.

How to get Chargify Webhook Response in .Net

I have already configure webhook url in chargify. This url is for webapi.
So i'm handling all events in webapi. But I want to know that how can we get the request parameter from chargify. If anyone have an example, would you please give me.
Below is the request from the chargify webhook's one event
you can get the below link for the webhook sending request for the events.
https://docs.chargify.com/webhooks#signup-success-payload
Please help me on this.
Thanks in Advance.
I tried the solution from above but it didn't work for me (probably because it's a 2015 solution and Chargify has made a few changes in the time).
What worked for me was:
[HttpPost]
[Route("test")]
[Consumes("application/x-www-form-urlencoded")]
public ActionResult Test([FromForm] RequestObject request)
If we will use RequestObject with ModelBinding, we have to create the data structure of the objects and variables we want to use.
For instance, for the signup_success event, the data structure for the objects Product, Customer and Customer Reference will be:
public class RequestObject
{
public string id { get; set; }
public Payload payload { get; set; }
}
public class Payload
{
public Subscription subscription { get; set; }
}
public class Subscription
{
public long id { get; set; }
public Product product { get; set; }
public Customer customer { get; set; }
}
public class Product
{
public long id { get; set; }
}
public class Customer
{
public long id { get; set; }
public string reference { get; set; }
}
Since it's submitted to the webhook url as form-parameters, so in MVC your signature would look similar to the following:
public ActionResult ReceiveWebhook(FormCollection webhookPayload, string signature_hmac_sha_256)
The parameter signature_hmac_sha_256 is included in the query string, so it's passed here.
You could then run different logic by using the event:
var eventName = webhookPayload["event"];

JSON.NET Object Deserialisation with class

I am using these classes:
public class MasteryPages
{
internal MasteryPages() { }
[JsonProperty("pages")]
public List<MasteryPage> Pages { get; set; }
[JsonProperty("summonerId")]
public long SummonerId { get; set; }
}
[Serializable]
public class MasteryPage
{
internal MasteryPage() { }
[JsonProperty("current")]
public bool Current { get; set; }
[JsonProperty("id")]
public long Id { get; set; }
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("talents")]
public List<Talent> Talents { get; set; }
}
[Serializable]
public class Talent
{
internal Talent() { }
[JsonProperty("id")]
public int Id { get; set; }
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("rank")]
public int Rank { get; set; }
}
This is the code I'm using to deserialise the object
//MASTERIES
var jsonMasteries = requester.CreateRequest(string.Format(RootUrl, Region) + string.Format(MasteriesUrl, summonerId));
var objAllMasteryPages = JsonConvert.DeserializeObject<MasteryPages>(jsonMasteries);
The jsonMasteries object is correctly serialized and gives me this:
http://pastebin.com/3dkdDHdx (Rather large, to view easily: go to http://www.jsoneditoronline.org/ and paste it)
The second line is giving me troubles however. Normally my object should be filled with the data. It unfortunately isn't and I have no idea what's wrong.
Anyone could help me out?
Your problem is in this part of serialized JSON: "42177333": { ... }
As I understand - this is some kind of ID and it's dynamic.
Possible solutions are:
One of possible resolutions is here: C# deserialize dynamic JSON
Cut this part of dynamic JSON.
Try to modify the serialization stuff to avoid this dynamic ID.
Thanks to sleepwalker I saw what was wrong. (Dynamic Id (number), first line)
Now, the James Newtonking JSON library has a solution for dynamic id's like this.
I edited my code to this:
var jsonMasteries = requester.CreateRequest(string.Format(RootUrl, Region) + string.Format(MasteriesUrl, summonerId));
var objAllMasteriePages = JsonConvert.DeserializeObject<Dictionary<long, MasteryPages>>(jsonMasteries).Values.FirstOrDefault().Pages;
(First line stays the same, the magic is in the second line)
Now, i use a dictionary with the key being my given Id, and my custom class.
This works wonders

MVC 4 EF5 - Add sub-entities error

I am getting an Object reference not set to an instance of an object error when trying to add multiple entity levels to my EF context.
Take the following three-level example class structure:
public class Forum
{
public int ID { get; set; }
public string Name { get; set; }
public virtual ICollection<Blog> Blogs { get; set; }
}
public class Blog
{
public int ID { get; set; }
public string Name { get; set; }
public int ForumID { get; set; }
public virtual Forum Forum { get; set; }
public virtual ICollection<Post> Posts { get; set; }
}
public class Post
{
public int ID { get; set; }
public string Name { get; set; }
public int BlogID { get; set; }
public virtual Blog Blog { get; set; }
}
For a given Forum, I want to add a new Blog with a new Post:
Forum MyForum = context.Forums.Find(1);
Blog MyBlog = new Blog { Name = "My New Blog" };
Post MyPost = new Post { Name = "My New Post" };
MyForum.Blogs.Add(MyBlog); // This WORKS
MyBlog.Posts.Add(MyPost); // This FAILS
context.SaveChanges(); // We never make it this far
I've tried every possible order combination, including placing context.SaveChanges() immediately after .Add(MyBlog). It seems like it's choking because there is no Blog.ID to use for Post.BlogID, but EF generates temporary key values for use in this situation.
Any ideas?
Hints at the answer (and the root problem) can be found at:
Entity Framework Uninitialised Collection
Entity Framework 4.1 Code First - Should many relationship ICollections be initialised
The "simple" solution is to manually initialize the Blog.Posts collection:
Blog MyBlog = new Blog { Name = "My New Post", Posts = new List<Post>() };
Alternatively, you can build this logic into the class constructor as recommended by Ladislav in the second link.
Basically, when you create a new object, the collection is null and not initialized as a List<>, so the .Add() call fails. The Forum.Blogs collection is able to lazy-load because it derives from the database context. Blog.Posts, however, is created from scratch, and EF can't help you, so the collection is null by default.

ServiceStack RazorRockstars Example - Reserved Route?

I have an issue with the RazorRockstars example. I have renamed the main route (/rockstars) on the Rockstars request class to /properties and now it no longer loads. It appears /properties route is reserved. Is this the case? I wish to use this route in my application.
Works:
[Route("/rockstars")]
[Route("/rockstars/{Id}")]
[Route("/rockstars/aged/{Age}")]
public class Rockstars
{
public int? Age { get; set; }
public int Id { get; set; }
}
Works:
[Route("/blahblahblah")]
[Route("/blahblahblah/{Id}")]
[Route("/blahblahblah/aged/{Age}")]
public class Rockstars
{
public int? Age { get; set; }
public int Id { get; set; }
}
Does not work:
[Route("/properties")]
[Route("/properties/{Id}")]
[Route("/properties/aged/{Age}")]
public class Rockstars
{
public int? Age { get; set; }
public int Id { get; set; }
}
Using /properties doesn't work in development because it matches a folder in your root directory (which hi-jacks the request), i.e. in this case VS.NET's Properties/ folder it uses to hold your projects AssemblyInfo.cs file.
It will work after you rename the Properties folder to something else, or once you deploy since deployment builds doesn't include the Properties folder.

Resources