英文:
How do I wrapper an existing C# DLL in a C# web API?
问题
以下是您要翻译的内容:
"First, I'm new to web APIs so maybe this is an ambitious first project.
My team manages a C# DLL that contains methods for several different applications used by one team at work. This DLL is used on hundreds of workstations and my team is interested in wrapping this DLL in a web API so DLL management will be less work and we can move into the 21st century. So, I copied the DLL folder into packages, created a reference in the web API project. Some of the methods return or require an object or object array.
Already tried creating a web API using 4.7x framework in VS 2015, as well as an ASP.NET Web API with MVC (2015) and today, an ASP.NET Core Web API in VS 2022.
Questions:
- Is this possible or am I misunderstanding the boundaries?
- When I tried this out using VS 2015 (this project uses 4.7x framework), it compiles just fine but gives me an HTTP error when the browser loads. How do I install this on an IIS instance and test it properly?
- Can objects be passed in and out of methods from the DLL using a web API?
- If I'm on the wrong path here, what's the best way to get on the right one?"
英文:
First, I'm new to web APIs so maybe this is an ambitious first project.
My team manages a C# DLL that contains methods for several different applications used by one team at work. This DLL is used on hundreds of workstations and my team is interested in wrapping this DLL in a web API so DLL management will be less work and we can move into the 21st century. So, I copied the DLL folder into packages, created a reference in the web API project. Some of the methods return or require an object or object array.
Already tried creating a web API using 4.7x framework in VS 2015, as well as an ASP.NET Web API with MVC (2015) and today, an ASP.NET Core Web API in VS 2022.
Questions:
- Is this possible or am I misunderstanding the boundaries?
- When I tried this out using VS 2015 (this project uses 4.7x framework), it compiles just fine but gives me an HTTP error when the browser loads. How do I install this on an IIS instance and test it properly?
- Can objects be passed in and out of methods from the DLL using a web API?
- If I'm on the wrong path here, what's the best way to get on the right one?
答案1
得分: 4
-
是的,这应该是可能的(但点3和点4将修改这一点):通常情况下,您的C# DLL可以用作API项目中的库。您可以像在任何其他C#项目中一样使用DLL提供的方法。
这里唯一的区别是,您将在API控制器操作内调用这些方法,并将它们的结果作为HTTP响应返回。 -
要在IIS实例上托管您的Web API,您需要按照以下一般步骤进行操作:
- 从Visual Studio中发布您的项目。您可以通过在解决方案资源管理器中右键单击项目并选择“发布”来执行此操作。这将生成一个“发布”配置文件,您可以选择发布到文件夹。
- 在您的计算机或服务器上打开Internet Information Services(IIS)管理器。您可以通过在运行对话框(Windows键+R)中键入“inetmgr”来执行此操作。
- 在IIS管理器中,右键单击“站点”,然后选择“添加网站”。您需要为其指定名称,将物理路径设置为已发布文件的位置,并设置端口号。
- 单击“确定”,您的站点应该正在运行。您可以通过在Web浏览器中键入“localhost:[端口]”来访问它。将“[端口]”替换为设置站点时选择的端口号。
如果出现HTTP错误,请查看日志以获取有关出现问题的详细信息。
-
是的,您可以在DLL的方法之间传递对象并返回对象,使用Web API。但是,您需要确保这些对象可以序列化为JSON(或者如果您更喜欢的话,XML),因为它们将通过HTTP进行传输。对于复杂对象,您可能需要创建DTO(数据传输对象),以匹配您的对象结构,但只包括要在API上公开的属性。
这是需要进行一些重新设计的地方。> 您可能希望在从Web API调用DLL的地方(内部)使用try/catch块。
然后,您可以使用适当的HTTP错误代码进行响应。
> 例如,如果您有一个失败的身份验证端点,您将希望返回401未经授权。
否则,未处理的异常会转化为500内部服务器错误,对于使用API的开发人员来说并不有帮助。
考虑使用Swagger来文档化/测试接口。 -
是的,但是:如果您处理的是建立在.NET Framework 4.x上的旧版DLL,并且在使用Web API进行封装时遇到问题,那么您可能需要考虑更全面的重新设计。
可能的选项包括:-
重构DLL为.NET标准库,如果可能的话。 .NET Standard 是一个旨在在所有.NET实现中可用的.NET API规范。这将允许您的库被.NET Framework和.NET Core应用程序使用。之后,您可以创建一个引用此.NET标准库的.NET Core Web API。然而,如果DLL使用.NET标准中不可用的API,则这种方法可能需要大量工作。
-
使用.NET Framework Web API:由于您的DLL是建立在.NET Framework 4.x上的,因此在您的Web API中继续使用.NET Framework可能会更容易。您仍然可以利用现代API的许多功能,并且与您的DLL一起工作应该更容易。
-
实施外观模式:创建一个新的层,将与您的DLL进行交互,并公开一个更现代、适合Web的接口。这可能是一个很好的折衷方案,允许您保留现有的DLL,同时提供现代API接口。
请参阅Adam Storr的“Facade Design Pattern: Still relevant in ASP.NET Core?”示例。 -
使用带有Windows兼容性包的.NET Core/.NET 5+ Web API:.NET Core 2.x及更高版本,以及.NET 5及更高版本,提供了一个Windows兼容性包,可以添加回一些仅在.NET Framework中可用的API。这可能允许您在更现代的.NET Core或.NET 5+ Web API中使用DLL。但请注意,不是所有.NET Framework API都可用,而且这只适用于Windows。
请参阅“Use the Windows Compatibility Pack to port code to .NET”。
-
重新设计如同任何其他设计一样,应该是迭代的过程。您可能不会一次做对,但随着每次尝试,您将更好地了解问题,并能够做出更明智的决策。
我建议进行全面的测试,以确保在重构和重新设计时功能保持一致。如果您的DLL没有良好的一组测试,那么首先创建这些测试可能是正确的第一步。
还要考虑是否有其他架构变更可以改进整体系统设计。这样的重新设计可能是一个较大的项目,但可能在可维护性、可扩展性和灵活性方面提供显
英文:
On your original questions
-
Yes, this should be possible (but point 3 and 4 will amend that): in general, your C# DLL could be used as a library in your API project. You could use the methods provided by the DLL as you would in any other C# project.
The only difference here is that you would be calling these methods inside your API controller actions and returning their results as HTTP responses. -
In order to host your web API on an IIS instance, you will need to follow these general steps:
- Publish your project from Visual Studio. You can do this by right-clicking on the project in Solution Explorer and selecting "Publish". This will generate a
publish
profile, and you can choose to publish to a folder. - Open the Internet Information Services (IIS) Manager on your machine or server. You can do this by typing "
inetmgr
" into the Run dialog (Windows Key + R). - In the IIS Manager, right-click on "
Sites
" and select "Add Website
". You will need to give it a name, set the physical path to the location of your published files, and set the port number. - Click
OK
and your site should be running. You can access it by typing "localhost:[port]
" into your web browser. Replace "[port]
" with the port number you chose when setting up the site.
If you are getting an HTTP error, check the logs to get more information about what is going wrong.
- Publish your project from Visual Studio. You can do this by right-clicking on the project in Solution Explorer and selecting "Publish". This will generate a
-
Yes, you can pass objects in and out of methods from the DLL using a web API. However, you will need to ensure that the objects are serializable to JSON (or XML if you prefer) since that is how they will be transmitted over HTTP. For complex objects, you might need to create DTOs (Data Transfer Objects) that match the structure of your objects but only include the properties that you want to expose over the API.
That is where some redesign start to be necessary.Joe Mayo adds in the comments:
> You might want to wrap the call to the DLL (from the Web API) in a try/catch block.
Then, you can respond with a proper HTTP Error code.
> E.g. if you have an authentication endpoint that fails, you'll want to return a 401 Unauthorized.
Otherwise, an unhandled exception translates into 500 Internal Server Error, which is not helpful to the developer consuming the API.
Consider using Swagger too, for documenting/testing the interface. -
Yes, but: if you are dealing with a legacy DLL that is built on .NET Framework 4.x, and you are having issues wrapping it with a web API, then you might need to consider a more comprehensive redesign.
Possible options are, for instance:-
Refactor the DLL into a .NET Standard Library, if possible. .NET Standard is a specification of .NET APIs that are intended to be available on all .NET implementations. This will allow your library to be consumed by both .NET Framework and .NET Core applications. After that, you can create a .NET Core Web API that references this .NET Standard Library. However, this approach may require significant work if the DLL uses APIs that are not available in .NET Standard.
-
Use a .NET Framework Web API: Since your DLL is built on .NET Framework 4.x, it might be easier to stick with a .NET Framework for your web API. You can still take advantage of many of the features of a modern API, and it should be easier to work with your DLL.
-
Implement a Facade Pattern: Create a new layer that will interact with your DLL and expose a more modern, web-friendly interface. This can be a good compromise that lets you keep the existing DLL while still offering a modern API interface.
See "Facade Design Pattern: Still relevant in ASP.NET Core?" by Adam Storr as an illustration. -
Use a .NET Core/.NET 5+ Web API with a Windows Compatibility Pack: .NET Core 2.x and later, as well as .NET 5 and later, offer a Windows Compatibility Pack that adds back some of the APIs that were only available in .NET Framework. This might allow you to use your DLL with a more modern .NET Core or .NET 5+ Web API. However, be aware that not all .NET Framework APIs are available, and this only works on Windows.
See "Use the Windows Compatibility Pack to port code to .NET"
-
As with any redesign, the process should be iterative. You might not get it right the first time, but with each attempt, you will understand the problem better and be able to make more informed decisions.
I would recommend a comprehensive set of tests to ensure that the functionality remains consistent as you refactor and redesign. If your DLL does not have a good set of tests, then creating those tests first might be the right first step.
Consider also if there are other architectural changes that could improve the overall system design. Such a redesign could be a larger project, but it might also offer significant benefits in terms of maintainability, scalability, and flexibility.
For example, suppose your DLL provides methods for user authentication. Instead of having this logic embedded in a DLL that needs to be distributed and referenced by multiple applications, you could create a User Authentication microservice. This microservice would expose endpoints for operations like "Login", "Register", "Forgot Password", etc. Your applications would then interact with this service over HTTP, removing the need to directly reference the DLL.
See ".NET Microservices: Architecture for Containerized .NET Applications" for illustrations.
答案2
得分: 3
这可能是可能的,还是我误解了边界?
不,这并不那么容易
当我尝试在VS 2015中尝试这个(这个项目使用4.7x框架),编译没有问题,但在浏览器加载时出现HTTP错误。如何在IIS实例上安装并正确测试它?
你应该已经在Visual Studio中拥有IIS(https://learn.microsoft.com/en-us/aspnet/web-forms/overview/deployment/visual-studio-web-deployment/deploying-to-iis);要测试API,你可以安装Swagger NuGet包(https://santansarah.github.io/swashbuckle/)
对象是否可以通过Web API在DLL中传入和传出方法?
是的,使用JSON非常容易
- string jsonString = JsonSerializer.Serialize(yourVar);
- JsonSerializer.Deserialize<YourObjectType>(jsonString);
如果我走错了路,那么走上正确道路的最佳方法是什么?
你走在正确的道路上
英文:
Is this possible or am I misunderstanding the boundaries?
no, it's just not that easy
When I tried this out using VS 2015 (this project uses 4.7x framework), it compiles just fine but gives me an HTTP error when the browser loads. How do I install this on an IIS instance and test it properly?
you should already have IIS in visual studio (https://learn.microsoft.com/en-us/aspnet/web-forms/overview/deployment/visual-studio-web-deployment/deploying-to-iis); to test the API you can install swagger nuget package (https://santansarah.github.io/swashbuckle/)
Can objects be passed in and out of methods from the DLL using a web API?
yes, very easy with json
- string jsonString = JsonSerializer.Serialize(yourVar);
- JsonSerializer.Deserialize<YourObjectType>(jsonString);
If I'm on the wrong path here, what's the best way to get on the right one?
you are on the right path
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论