我想在此示例PizzaOrderDialog.cs
中将订单保存到数据库我可以将DbConext注入控制器,例如这一个https://github.com/Microsoft/BotBuilder/blob/master/CSharp/Samples/PizzaBot/Controllers/MessagesController.cs,但如何在PizzaOrderDialog.cs
中使用它我不能将DbContext作为构造函数参数传递给PizzaOrderDialog类,因为PizzaOrderDialog对象将被序列化然后反序列化。
最好的方法是什么?提前谢谢!
MessageController.cs
[BotAuthentication]
public class MessagesController : ApiController
{
private static IForm<PizzaOrder> BuildForm()
{
var builder = new FormBuilder<PizzaOrder>();
ConditionalDelegate<PizzaOrder> isBYO = (pizza) => pizza.Kind == PizzaOptions.BYOPizza;
ConditionalDelegate<PizzaOrder> isSignature = (pizza) => pizza.Kind == PizzaOptions.SignaturePizza;
ConditionalDelegate<PizzaOrder> isGourmet = (pizza) => pizza.Kind == PizzaOptions.GourmetDelitePizza;
ConditionalDelegate<PizzaOrder> isStuffed = (pizza) => pizza.Kind == PizzaOptions.StuffedPizza;
return builder
// .Field(nameof(PizzaOrder.Choice))
.Field(nameof(PizzaOrder.Size))
.Field(nameof(PizzaOrder.Kind))
.Field("BYO.Crust", isBYO)
.Field("BYO.Sauce", isBYO)
.Field("BYO.Toppings", isBYO)
.Field(nameof(PizzaOrder.GourmetDelite), isGourmet)
.Field(nameof(PizzaOrder.Signature), isSignature)
.Field(nameof(PizzaOrder.Stuffed), isStuffed)
.AddRemainingFields()
.Confirm("Would you like a {Size}, {BYO.Crust} crust, {BYO.Sauce}, {BYO.Toppings} pizza?", isBYO)
.Confirm("Would you like a {Size}, {&Signature} {Signature} pizza?", isSignature, dependencies: new string[] { "Size", "Kind", "Signature" })
.Confirm("Would you like a {Size}, {&GourmetDelite} {GourmetDelite} pizza?", isGourmet)
.Confirm("Would you like a {Size}, {&Stuffed} {Stuffed} pizza?", isStuffed)
.Build()
;
}
internal static IDialog MakeRoot()
{
return new PizzaOrderDialog(BuildForm);
}
public async Task<Message> Post([FromBody]Message message)
{
return await Conversation.SendAsync(message, MakeRoot);
}
}
PizzaOrderDialog.cs
[LuisModel("4311ccf1-5ed1-44fe-9f10-a6adbad05c14", "6d0966209c6e4f6b835ce34492f3e6d9")]
[Serializable]
public class PizzaOrderDialog : LuisDialog
{
private readonly BuildForm<PizzaOrder> MakePizzaForm;
internal PizzaOrderDialog(BuildForm<PizzaOrder> makePizzaForm)
{
this.MakePizzaForm = makePizzaForm;
}
[LuisIntent("")]
public async Task None(IDialogContext context, LuisResult result)
{
await context.PostAsync("I'm sorry. I didn't understand you.");
context.Wait(MessageReceived);
}
[LuisIntent("OrderPizza")]
[LuisIntent("UseCoupon")]
public async Task ProcessPizzaForm(IDialogContext context, LuisResult result)
{
var entities = new List<EntityRecommendation>(result.Entities);
if (!entities.Any((entity) => entity.Type == "Kind"))
{
// Infer kind
foreach (var entity in result.Entities)
{
string kind = null;
switch (entity.Type)
{
case "Signature": kind = "Signature"; break;
case "GourmetDelite": kind = "Gourmet delite"; break;
case "Stuffed": kind = "stuffed"; break;
default:
if (entity.Type.StartsWith("BYO")) kind = "byo";
break;
}
if (kind != null)
{
entities.Add(new EntityRecommendation("Kind") { Entity = kind });
break;
}
}
}
var pizzaForm = new FormDialog<PizzaOrder>(new PizzaOrder(), this.MakePizzaForm, FormOptions.PromptInStart, entities);
context.Call<PizzaOrder>(pizzaForm, PizzaFormComplete);
}
private async Task PizzaFormComplete(IDialogContext context, IAwaitable<PizzaOrder> result)
{
PizzaOrder order = null;
try
{
order = await result;
}
catch (OperationCanceledException)
{
await context.PostAsync("You canceled the form!");
return;
}
if (order != null)
{
await context.PostAsync("Your Pizza Order: " + order.ToString());
}
else
{
await context.PostAsync("Form returned empty response!");
}
context.Wait(MessageReceived);
}
enum Days { Saturday, Sunday, Monday, Tuesday, Wednesday, Thursday, Friday };
[LuisIntent("StoreHours")]
public async Task ProcessStoreHours(IDialogContext context, LuisResult result)
{
var days = (IEnumerable<Days>)Enum.GetValues(typeof(Days));
PromptDialog.Choice(context, StoreHoursResult, days, "Which day of the week?");
}
private async Task StoreHoursResult(IDialogContext context, IAwaitable<Days> day)
{
var hours = string.Empty;
switch (await day)
{
case Days.Saturday:
case Days.Sunday:
hours = "5pm to 11pm";
break;
default:
hours = "11am to 10pm";
break;
}
var text = $"Store hours are {hours}";
await context.PostAsync(text);
context.Wait(MessageReceived);
}
}
答案 0 :(得分:0)
您要求做的事情违反了MVC范例。
那是 - 你不应该做一些控制器类型的功能&amp;直接在您的演示文稿(视图)图层的代码中与db模型交互,名为PizzaOrderDialog.cs
你应该将db_context的单例引用注入到你的控制器中(你已经有了这部分)
AND
在控制器中添加函数以封装对话框的这些db_context交互,然后使用BuildForm<PizzaOrder> makePizzaForm
将这些函数的结果注入到Dialog构造函数中。
即使有说,根据用户在对话框中选择的内容提供5x4x10建议的地图 - 将所有内容传递给序列化(如您所述)并让您的服务器端视图逻辑在PizzaOrderDialog.cs中使用所有可能性视图模型比尝试公开模型层访问更好。
对于具体的排序提交,我将向控制器添加一个静态方法,您可以从对话框中调用该方法,再次封装db_context所需的任何交互以实现此目的。