#PostMapping(produces = "application/json", consumes = "application/json")
public ResponseEntity<Book> addBook(
#RequestBody(description = "Book to add.", required = true,
content = #Content(
schema=#Schema(implementation = Book.class)))
#Valid Book book
) {
return ResponseEntity.ok(bookRepository.add(Book));
}
2.
#PostMapping(produces = "application/json", consumes = "application/json")
public ResponseEntity<BasicBook> addBook(
#RequestBody(description = "Book to add.", required = true,
content = #Content(
schema=#Schema(allOf = BasicBook.class, oneOf = {
HomeScience.class, GeneralScience.class })))
#Valid BasicBook book
) {
return ResponseEntity.ok(bookRepository.add(Book));
}
Above snippet 1. is working fine. In the Swagger UI I can see the RequestBody with example value where I can execute that.
but for snippet 2. when I am trying inheritance (i.e. oneOf, allOf or anyOf), this schema is not working.
Only BasicBook properties are coming in (Swagger UI)RequestBody's example value.
I have tried with #Parameter also. Here is the code
3.
#PostMapping(produces = "application/json", consumes = "application/json")
public ResponseEntity<BasicBook> addBook(
#Parameter(required = true, description = "DTO for book.", content = {
#Content(mediaType = "application/json", schema = #Schema(allOf = BasicBook.class, oneOf = {
HomeScience.class, GeneralScience.class }, discriminatorMapping = {
#DiscriminatorMapping(value = "HOME", schema = HomeScience.class),
#DiscriminatorMapping(value = "GENERAL", schema = GeneralScience.class) }, discriminatorProperty = "type")) })
#RequestBody #Valid BasicBook book
) {
return ResponseEntity.ok(bookRepository.add(Book));
}
snippet 3. also not giving desired result.
How can I use oneOf, allOf or anyOf in the RequestBody.
Related
I want to send an email using graph explorer and i need to send to a number of recipients .
How can i construct a list of emails in the body using c# .
So far i have
var emailTo = "test1#acme.com,test2#acme.com";
var emailList = new List<string>();
foreach (var item in emailTo.Split(','))
{
emailList.Add(item);
}
var emailbody = new
{
message = new
{
subject = "test details",
body = new
{
contentType = "Text",
content = "The test details content."
},
toRecipients = emailList
}
};
but when i look at the request it isnt constructed correctly as the following Graph api expects.
{
"message": {
"subject": "Meet for lunch?",
"body": {
"contentType": "Text",
"content": "The new cafeteria is open."
},
"toRecipients": [
{
"emailAddress": {
"address": "garthf#contoso.com"
}
}
]
}
}
How can i set an array of recipients ?
You have to create a list of Recipients and assign it to ToRecipients
var toRecipients = new List<Recipient>();
var emailTo = "test1#acme.com,test2#acme.com";
foreach (var recipient in emailTo.Split(','))
{
toRecipients.Add(new Recipient
{
EmailAddress = new EmailAddress
{
Address = recipient
}
});
}
var message = new Message
{
Subject = "Subject",
Body = new ItemBody
{
ContentType = BodyType.Html,
Content = "<div>Text</div>"
},
ToRecipients = toRecipients
};
I have seeded the database using code first migration, however I noticed when I view the seeded data in index.html, the data is replicated.
This is the configuration file were I seeded the data:
internal sealed class Configuration : DbMigrationsConfiguration
{
public Configuration()
{
AutomaticMigrationsEnabled = false;
}
protected override void Seed(OnlineBookStore.Models.OnlineBookStoreDB context)
{
var books = new System.Collections.Generic.List<Book>
{
new Book {
BookStatus = new BookStatus { Status = "New" },
Genre = new Genre { Name = "Thriller" },
Author = new Author { Name = "Paula Hawkins" },
Title = "The Girl On The Train",
Description = "Rachel catches the same commuter train morning. ",
ISBN = 0552779776,
},
new Book
{
BookStatus = new BookStatus { Status = "Best Seller" },
Genre = new Genre { Name = "Childrens" },
Author = new Author { Name = "Roald Dahl" },
Title = "The Witches",
Description = "Beware. Real witches dress in ordinary clothes",
ISBN = 0141365471,
},
},
};
books.ForEach(s =>context.Books.AddOrUpdate(p => new { p.ISBN, p.Title } ));
context.SaveChanges();
}
}
}
I am really unsure of were I am going wrong, spent days on this!
Really appreciate anyones help! thanks!
You need to specify the key in AddOrUpdate to prevent duplicates since Seed() runs with every update-database issued.
// build your books collection
var books = new []
{
new Book {
BookStatus = new BookStatus { Status = "New" },
Genre = new Genre { Name = "Thriller" },
Author = new Author { Name = "Paula Hawkins" },
Title = "The Girl On The Train",
Description = "Rachel catches the same commuter train morning. ",
ISBN = 0552779776,
},
new Book
{
BookStatus = new BookStatus { Status = "Best Seller" },
Genre = new Genre { Name = "Childrens" },
Author = new Author { Name = "Roald Dahl" },
Title = "The Witches",
Description = "Beware. Real witches dress in ordinary clothes",
ISBN = 0141365471,
},
},
};
context.Books.AddOrUpdate(p => new { p.ISBN, p.Title }, books);
context.SaveChanges();
See http://thedatafarm.com/data-access/take-care-with-ef-4-3-addorupdate-method/
I have a query that returns something like this:
OBJECT | QTY | ......
Random_Name_1 | 5 | .....
Random_Name_2 | 3 | ......
I want to return a j-son like this
{"Success": true, "Message": "Total rows 8", "Data": { "Random_Name_1": {"QTY": 5 ... }, "Random_Name_2": {"QTY": 3 ... } } }
How can i accomplish this in a web API made on ASP.NET MVC4?
You could try this:
// your data
var q = new[]
{
new {OBJECT = "Random_Name_1", QTY = 5, TYPE = "A"},
new {OBJECT = "Random_Name_2", QTY = 3, TYPE = "B"},
new {OBJECT = "Random_Name_3", QTY = 8, TYPE = "B"}
};
// construct the object
var obj = new
{
Success = true,
Message = string.Format("Total rows {0}", q.Count()),
Data = q.ToDictionary(
item => item.OBJECT,
item => item.GetType().GetProperties()
.Where(p => p.Name != "OBJECT")
.ToDictionary(p => p.Name, p => p.GetValue(item, null)))
};
// serialize the object (note that you don't need to do that from web api)
var json = JsonConvert.SerializeObject(obj);
Note taht if you already know the structure of data (i.e. the columns) then you can make it more efficient by avoiding reflection. Means:
var obj = new
{
Success = true,
Message = string.Format("Total rows {0}", q.Count()),
Data = q.ToDictionary(
item => item.OBJECT,
item => new { item.QTY, item.TYPE })
};
Here is how i solved it, on monday I'll probably change it to be reflective..
var x = tw.spCall(type).ToList();
if (x.Count() == 0)
return new { Success = false, Message = "No data!" };
DataSet temp = new DataSet();
foreach (var y in x) {
if (temp.Tables[y.EQUIPMENT] == null) {
temp.Tables.Add(y.EQUIPMENT);
temp.Tables[y.EQUIPMENT].Columns.Add("id_key");
temp.Tables[y.EQUIPMENT].Columns.Add("PartNumber");
...
};
DataRow row = temp.Tables[y.EQUIPMENT].Rows.Add();
row.SetField("id_key",y.id_key);
row.SetField("PartNumber",y.PartNumber);
...
}
return JsonConvert.SerializeObject(temp, Newtonsoft.Json.Formatting.None);
I have ASP.NET MVC Project and I have some module. Some modules have pagination. For test and understand MvcSiteMapProvider I working with one module Forum and created ForumDynamicNodeProvider class
public class ForumDynamicNodeProvider : DynamicNodeProviderBase
{
private readonly IForumsService _forumsService;
public ForumDynamicNodeProvider(IForumsService forumsService)
{
this._forumsService = forumsService;
}
public override IEnumerable<DynamicNode> GetDynamicNodeCollection(ISiteMapNode node)
{
string rootTitle = ManagerLocalization.Get("Forums", "FORUMS");
var nodes = new List<DynamicNode>
{
new DynamicNode
{
Title = rootTitle,
Controller = "Forums",
Action = "Index",
Key = "forum_home"
}
};
var forums = this._forumsService.GetForums<ForumNode>().ToList();
var topics = this._forumsService.GetTopics<TopicNode>().ToList();
foreach (var forum in forums)
{
var parentForum = this.GetParentForum(forums, forum);
string parentKey = parentForum?.Id.ToString() ?? "home";
var forumRouteValue = new Dictionary<string, object> { { "forumName", forum.NameTranslit } };
nodes.Add(new DynamicNode
{
Key = $"forum_{forum.Id}",
ParentKey = $"forum_{parentKey}",
Title = forum.Name,
Controller = "Forums",
Action = "ShowForum",
RouteValues = forumRouteValue
});
}
foreach (var topic in topics)
{
var forum = forums.FirstOrDefault(item => item.Id == topic.ForumId);
var forumRouteValue = new Dictionary<string, object> { { "forum", forum.NameTranslit }, { "topicName", topic.TitleTranslite }, {"page", 0 } };
nodes.Add(new DynamicNode
{
Key = $"topic_{topic.Id}",
ParentKey = $"forum_{topic.ForumId}",
Title = topic.Title,
Controller = "Forums",
Action = "ShowTopic",
RouteValues = forumRouteValue
});
}
return nodes;
}
private ForumNode GetParentForum(List<ForumNode> forums, ForumNode forum)
{
if (forum.ForumId > 0)
{
return forums.FirstOrDefault(item => item.Id == forum.ForumId);
}
return null;
}
}
But I can't found a good decision for pagination. For easy I can use page prefix for key and make duplicate DynamicNode. But it's bad idea, because when I have example 1000 topics and each topic have 20 page I must create 20000 DynamicNode. Maybe have other decision?
For ambient context (such as page number) you can use PreservedRouteParameters to force a match on any value for the specified keys. These keys match either route values or query string parameters from the request (route values take precedence if they are the same).
foreach (var forum in forums)
{
var parentForum = this.GetParentForum(forums, forum);
string parentKey = parentForum?.Id.ToString() ?? "home";
var forumRouteValue = new Dictionary<string, object> { { "forumName", forum.NameTranslit } };
// Always match the "page" route value regardless of its value
var forumPreservedRouteParameters = new List<string>() { "page" };
nodes.Add(new DynamicNode
{
Key = $"forum_{forum.Id}",
ParentKey = $"forum_{parentKey}",
Title = forum.Name,
Controller = "Forums",
Action = "ShowForum",
RouteValues = forumRouteValue,
PreservedRouteParameters = forumPreservedRouteParameters
});
}
NOTE: When you use PreservedRouteParameters, they are included in the generated URL from the current request if provided and not included in the URL if not provided in the request. Therefore, if you have more than one page number in the same ancestry you need to have a separate route key name for each one or the current page number will be passed to the ancestor nodes from the current request.
I've been following along with a tutorial by Julie Lerman about using EF CodeFirst to generate the database from code. I'm using MVC4 and working with the default controllers. All I want to do is generate the database. However, in her tutorial, she's working with a console application and calling a create_blog method in her Main function. The create_blog function does the work of creating the database as the name suggests.
In my Global.asax, I have this:
Database.SetInitializer(new CIT.Models.SampleData());
This is my SampleData class:
public class SampleData : CreateDatabaseIfNotExists<Context>
{
protected override void Seed(Context context)
{
base.Seed(context);
new List<Software> {
new Software { Title = "Adobe Creative Suite", Version = "CS6", SerialNumber = "1234634543", Platform = "Mac", Notes = "Macs rock!", PurchaseDate = "2012-12-04", Suite = true, SubscriptionEndDate = null, SeatCount = 4, SoftwareTypes = new List<SoftwareType> { new SoftwareType { Type="Suite" }}, Locations = new List<Location> { new Location { LocationName = "Paradise" }}, Publishers = new List<SoftwarePublisher> { new SoftwarePublisher { Publisher = "Adobe" }}},
new Software { Title = "Apple iLife", Version = "2012", SerialNumber = "123463423453", Platform = "Mac", Notes = "Macs still rock!", PurchaseDate = "2012-11-04", Suite = true, SubscriptionEndDate = null, SeatCount = 4, SoftwareTypes = new List<SoftwareType> { new SoftwareType { Type="Suite" }}, Locations = new List<Location> { new Location { LocationName = "81st Street" }}, Publishers = new List<SoftwarePublisher> { new SoftwarePublisher { Publisher = "Apple" }}},
new Software { Title = "Microsoft Office", Version = "2012", SerialNumber = "12346231434543", Platform = "PC", Notes = "Macs really rock!", PurchaseDate = "2011-12-04", Suite = true, SubscriptionEndDate = null, SeatCount = 4, SoftwareTypes = new List<SoftwareType> { new SoftwareType { Type="Suite" }}, Locations = new List<Location> { new Location { LocationName = "Paradise" }}, Publishers = new List<SoftwarePublisher> { new SoftwarePublisher { Publisher = "Microsoft" }}}
}.ForEach(s => context.Software.Add(s));
}
}
I get no errors when I compile. I just get no database. I looked in my App_Data and all that's there is the default database. I have a dbContext that is getting called because when I had errors in it, they pointed to that file. Do I need to have some kind of create method that is called when the site first compiles?
SetInitializer only sets the initializer strategy and the strategy is executed the first time you access the database. Try adding the following after calling SetInitializer
using (var context = new Context()) { context.Database.Initialize(true); }