ASP.NET Core中异步控制器方法的F#语法

编程入门 行业动态 更新时间:2024-10-26 21:36:01
本文介绍了ASP.NET Core中异步控制器方法的F#语法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我是F#的新手,正在尝试将一些C#ASP.NET Core代码转换为F#

I'm new to F# and trying to translate some C# ASP.NET Core code into F#

有一个C#控制器这里,以及可正常翻译的F#控制器此处

There is a C# controller here, and a working translated F# controller here

即使我可以使用它,我似乎也无法弄清楚如何使控制器动作异步.这些方法在注入的Commands对象和Queries对象上调用异步代码.命令和查询当前在C#中实现.

even though I got it working, I can't seem to figure out how to make the controller actions async. The methods call async code on a Commands object and a Queries object that are injected. The Commands and Queries are currently implemented in C#.

例如,几个异步C#控制器方法是:

So for example a couple of the async C# controller methods are:

public async Task<IEnumerable<ToDoItem>> Get() { return await queries.GetAll(); } [HttpGet("{id}", Name = "GetTodo")] public async Task<IActionResult> GetById(string id) { var item = await queries.Find(id); if (item == null) { return NotFound(); } return new ObjectResult(item); } public async Task<IActionResult> Create([FromBody] ToDoItem item) { if (item == null) { return BadRequest(); } if (string.IsNullOrEmpty(item.Id)) item.Id = Guid.NewGuid().ToString(); await commands.Add(item); return CreatedAtRoute("GetTodo", new { id = item.Id }, item); }

我已经将它们翻译成F#了:

and I've translated those to F# like this:

[<HttpGet>] member __.Get() = __.Queries.GetAll() // this should be awaited [<HttpGet("{id}", Name = "GetFSTodo")>] member __.GetToDoItem(id) = let data = __.Queries.Find(id) // this should be awaited if isNull data then __.NotFound() :> IActionResult else new ObjectResult(data) :> IActionResult [<HttpPost>] member __.Create([<FromBody>] item:ToDoItem) = item.Id <- Guid.NewGuid().ToString() (__.Commands.Add(item)) |> ignore // this should be awaited let rv = new RouteValueDictionary() rv.Add("id",item.Id) __.CreatedAtRoute("GetTodo", rv, item) :> IActionResult

这些方法有效,但是我认为它们没有正确完成,因为它们没有等待对查询和命令的异步调用.我经过反复尝试已经苦苦挣扎了几个小时,但是我为使控制器方法异步所做的每一次尝试都导致它们即使返回200状态代码也不会向浏览器返回任何数据.您可以在 F#控制器

These methods work but I think they are not correctly done since they aren't awaiting the async calls on Queries and Commands. I've thrashed for some hours with trial and error but every attempt I've made to make the controller methods async results in them not returning any data to the browser even though they return a 200 status code. You can see some of my attempts commented out in the F# controller

希望一些F#专家可以帮助我正确翻译这些方法.目前在ASP.NET Core的F#方面存在一些非常糟糕的工具问题,这对于像我这样的新手来说更加困难.我已经在自述文件

Hoping some F# guru(s) could help me translate those methods correctly. There are some pretty bad tooling issues currently in terms of F# with ASP.NET Core which makes it more difficult for a newbie like me. I've mentioned those issues in the readme

代码中还有一些其他方法,但是我认为如果我可以学习如何解决这些方法,那么相同的解决方案可能会应用于其他方法.

There are a few additional methods in the code but I figure if I can learn how to solve for these methods then the same solution will probably apply to the other methods.

代码位于公共存储库中,因此只要安装了最新的VS更新和最新的ASP.NET Core工具,您就可以在VS 2015中轻松尝试

The code is in a public repository so you can easily try it in VS 2015 as long as you have the latest VS updates and the latest ASP.NET Core tooling installed

更新:

由于Mark Seemann的链接,我能够使这种方法异步工作

thanks to the linked post by Mark Seemann, I was able to get this method working async

[<HttpGet("{id}", Name = "GetFSTodo")>] member __.GetToDoItem(id) = async { let! data = __.Queries.Find(id) |> asyncReturn if isNull data then return __.NotFound() :> IActionResult else return new ObjectResult(data) :> IActionResult } |> Async.StartAsTask

通过使用辅助功能

let asyncReturn x = async { return x }

我仍然在努力使用这种方法

I'm still struggling with this method

[<HttpGet>] member __.Get() = async { let! data = __.Queries.GetAll() |> asyncReturn return data } |> Async.StartAsTask

从此C#方法翻译的

:

which is translated from this C# method:

[HttpGet] public async Task<IEnumerable<ToDoItem>> Get() { return await queries.GetAll(); }

异步F#方法可以工作,但它产生的json输出与C#版本不同

the async F# method works but it produces different json output than the C# version

C# [{"id":"4f4e1596-6a48-4854-9982-7a2568aa1b1b","title":"add input validation","isDone":false,"dateAdded":"2016-09-20T21:16:04.8791044Z"},{"id":"9929b657-6a53-40b6-8c1c-1e4d0db593cd","title":"make F# controller async","isDone":false,"dateAdded":"2016-09-21T19:36:44.6650776Z"},{"id":"5bb5f544-6289-4051-ad65-d0dc016128e7","title":"learn F# basics","isDone":true,"dateAdded":"2016-09-22T11:59:00"},{"id":"e5e06118-c49f-496a-8175-9719ea72beed","title":"monkey business","isDone":false,"dateAdded":"2016-09-22T16:22:20.3133161Z"},{"id":"af0db8f2-6b49-4e31-86fa-e27c8e091f42","title":"funky bidness","isDone":false,"dateAdded":"2016-09-22T16:23:35.1175195Z"}] F# {"result":[{"id":"4f4e1596-6a48-4854-9982-7a2568aa1b1b","title":"add input validation","isDone":false,"dateAdded":"2016-09-20T21:16:04.8791044Z"},{"id":"9929b657-6a53-40b6-8c1c-1e4d0db593cd","title":"make F# controller async","isDone":false,"dateAdded":"2016-09-21T19:36:44.6650776Z"},{"id":"5bb5f544-6289-4051-ad65-d0dc016128e7","title":"learn F# basics","isDone":true,"dateAdded":"2016-09-22T11:59:00"},{"id":"e5e06118-c49f-496a-8175-9719ea72beed","title":"monkey business","isDone":false,"dateAdded":"2016-09-22T16:22:20.3133161Z"},{"id":"af0db8f2-6b49-4e31-86fa-e27c8e091f42","title":"funky bidness","isDone":false,"dateAdded":"2016-09-22T16:23:35.1175195Z"}],"id":65,"exception":null,"status":5,"isCanceled":false,"isCompleted":true,"creationOptions":0,"asyncState":null,"isFaulted":false}

所以我仍然可以在如何使F#版本产生预期输出方面使用一些帮助

so I still could use some help on how to make the F# version produce the expected output

推荐答案

更新2016-09-28

UPDATED 2016-09-28

感谢Ruben Bartelink,这是我的控制器现在正确实现为异步并处理C#和F#异步模式之间的细微差别的样子:

Thanks to Ruben Bartelink this is what my controller looks like now correctly implemented as async and handling the nuances that differ between C# and F# async patterns:

namespace FSharp.WebLib open System open Microsoft.AspNetCore.Mvc open Microsoft.AspNetCore.Routing open Microsoft.AspNetCore.JsonPatch open FSharp.Models module ActionResult = let ofAsync (res: Async<IActionResult>) = res |> Async.StartAsTask [<Route("api/[controller]")>] type FSToDoController(commands: IToDoCommands, queries: IToDoQueries) = inherit Controller() [<HttpGet>] member this.Get() = ActionResult.ofAsync <| async { let! data = queries.GetAll() return JsonResult(data) :> _ } [<HttpGet("{id}", Name = "GetFsToDo")>] member this.Get(id) = ActionResult.ofAsync <| async { let! res = queries.Find id match res with | None -> return this.NotFound() :> _ | Some data -> return ObjectResult(data) :> _ } // create [<HttpPost>] member this.Post([<FromBody>] item:ToDoItem) = ActionResult.ofAsync <| async { if not this.ModelState.IsValid then return this.BadRequest() :> _ else let item = { item with Id = Guid.NewGuid() |> string } do! commands.Add item let rv = RouteValueDictionary() rv.Add("id",item.Id) return this.CreatedAtRoute("GetFsToDo", rv, item) :> _ } // update [<HttpPut("{id}")>] member this.Put(id:String, [<FromBody>] item:ToDoItem) = ActionResult.ofAsync <| async { if (not this.ModelState.IsValid) || String.IsNullOrEmpty item.Id then return this.BadRequest() :> _ else let! res = queries.Find id match res with | None -> return this.NotFound() :> _ | Some toDo -> do! commands.Update item return NoContentResult() :> _ }

对于其他有兴趣学习F#(尤其是在ASP.NET Core中使用)的人来说,这是上的.md"rel =" noreferrer>概念验证项目,它同时具有ToDo列表后端Web api的C#和F#实现,这两者都是从使用聚合物Web组件实现的前端使用的.同时以两种语言实现模型和数据访问,以便为像我这样的C#开发人员学习F#提供很好的比较

for anyone else interested in learning F# particularly for use in ASP.NET Core, this is part of a proof of concept project on github that has both C# and F# implementations of a ToDo list back end web api both of which are consumed from a front end implemented with polymer web components. Models and data access are also implemented in both languages to provide a good comparison for C# devs like myself to learn F#

更多推荐

ASP.NET Core中异步控制器方法的F#语法

本文发布于:2023-11-05 07:21:48,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1560244.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:控制器   语法   方法   ASP   NET

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!