红着眼 2024-03-24 13:45 采纳率: 27.8%
浏览 17
已结题

C# Owin搭建API具体操作问题。

C# Owin搭建API,新手遇到的问题。完整代码已列出,麻烦大家耽误休息时间帮小弟看看,不胜感激。
button2_Click通过WebApiHelper调用GetUser方法是可以正常调用的。
button3_Click调用GetUserB方法怎么通过WebApiHelper去实现呢?
button4_Click方法怎么实现呢?
我换了好多种写法,要不就是404,或者是传递的[FromBody]参数在GetUserC方法中调试是null的。
请帮我实现button3_Click和button4_Click的方法。感谢。

Win窗体操作代码。

using System;
using System.Windows.Forms;

namespace OwinSelfhostDemo
{
    public partial class MainFrm : Form
    {
        public MainFrm()
        {
            InitializeComponent();
        }

        //启动服务
        private void button1_Click(object sender, EventArgs e)
        {
            this.button1.Enabled = false;
            Microsoft.Owin.Hosting.WebApp.Start<Startup>("http://localhost:8001");
        }

        //调用GetUser方法
        private void button2_Click(object sender, EventArgs e)
        {
            WebApiHelper wApi = new WebApiHelper("http://localhost:8001");
            string str = wApi.GetMethod("/api/Test/GetUser?userID=123");
            MessageBox.Show(str);
        }

        //调用GetUserB方法
        private void button3_Click(object sender, EventArgs e)
        {
            WebApiHelper wApi = new WebApiHelper("http://localhost:8001");
            string url = "/api/Test/GetUserB";
            string postDataStr = "{\"userID\":\"123\"}\"}";
            string response = wApi.PostMethod(postDataStr, url);
            MessageBox.Show(response);
        }

        //调用GetUserC方法
        private void button4_Click(object sender, EventArgs e)
        {
            //代码实现
        }

        //程序退出
        private void MainFrm_FormClosing(object sender, FormClosingEventArgs e)
        {
            System.Environment.Exit(0);
        }
    }
}

Startup.cs方法

using Owin;
using System.Collections.Generic;
using System.Web.Http;
using System.Net.Http.Headers;
using Microsoft.Owin.Cors;
using Beginor.Owin.StaticFile;
using System.Web.Http.Cors;
//[assembly: OwinStartup(typeof(OwinSelfhostDemo.Startup))]
namespace OwinSelfhostDemo
{
    public class Startup
    {
         // This code configures Web API. The Startup class is specified as a type
        // parameter in the WebApp.Start method.
        public void Configuration(IAppBuilder appBuilder)
        {
            // Configure Web API for self-host. 
            HttpConfiguration config = new HttpConfiguration();
            //跨域配置,经测试有效
            config.EnableCors(new EnableCorsAttribute("*", "*", "*"));
            config.Routes.MapHttpRoute(name: "DefaultApi",
                routeTemplate: "api/{controller}/{action}/{id}",
                defaults: new { cotroller = "Test", action = RouteParameter.Optional, id = RouteParameter.Optional });
            config.Formatters.XmlFormatter.SupportedMediaTypes.Clear();
            config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));
            appBuilder.UseWebApi(config);

            //静态文件托管
            appBuilder.Map("/pages", map =>
            {
                // 允许跨域
                map.UseCors(CorsOptions.AllowAll);
                map.UseStaticFile(new StaticFileMiddlewareOptions
                {
                    RootDirectory = @"../Debug/pages",
                    DefaultFile = "Pages/index.html",
                    EnableETag = true,
                    EnableHtml5LocationMode = true,
                    MimeTypeProvider = new MimeTypeProvider(new Dictionary<string, string>
                    {
                        { ".html", "text/html" },
                        { ".htm", "text/html" }                       
                    })
                });
            });
        }
    }
}

TestController.cs方法

using System.Web.Http;

namespace OwinSelfhostDemo.Controllers
{
    public class TestController : ApiController
    {
        public string Get()
        {
            return "Get方法被调用";
        }

        public string GetUser(string userID)
        {
            return "GetUser方法被调用,userID="+ userID;
        }

        public IHttpActionResult GetUserB(string userID)
        {
            //返回Json格式字符串
            return Json(new { a = 1, b = 2 });
        }

        [HttpPost]
        public IHttpActionResult GetUserC(int userID, [FromBody] string json)
        {
            return Json(json);
        }
    }
}

WebApiHelper.cs调用辅助类方法

using System;
using System.IO;
using System.Net;
using System.Text;

namespace OwinSelfhostDemo
{
    public class WebApiHelper
    {
        private string webApiUrl = "";
        public WebApiHelper(string apiUrl)
        {
            webApiUrl = apiUrl;
        }

        #region PostMethod
        public string PostMethod(string postDataStr, string url)
        {
            url = webApiUrl + url;
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
            request.Method = "POST";
            request.ContentType = "application/json";

            Stream myRequestStream = request.GetRequestStream();
            StreamWriter myStreamWriter = new StreamWriter(myRequestStream, System.Text.Encoding.UTF8);
            myStreamWriter.Write(postDataStr);
            myStreamWriter.Close();

            HttpWebResponse response = (HttpWebResponse)request.GetResponse();
            Stream myResponseStream = response.GetResponseStream();
            StreamReader myStreamReader = new StreamReader(myResponseStream, System.Text.Encoding.UTF8);
            string retString = myStreamReader.ReadToEnd();
            myStreamReader.Close();
            myResponseStream.Close();

            return retString;
        }
        #endregion

        #region GetMethod
        public string GetMethod(string url)
        {
            url = webApiUrl + url;
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
            request.Method = "GET";
            //request.ContentType = "text/html;charset=UTF-8"; 
            request.ContentType = "application/json";
            HttpWebResponse response = (HttpWebResponse)request.GetResponse();
            Stream myResponseStream = response.GetResponseStream();
            StreamReader myStreamReader = new StreamReader(myResponseStream, Encoding.UTF8);
            string retString = myStreamReader.ReadToEnd();
            myStreamReader.Close();
            myResponseStream.Close();
            return retString;
        }
        #endregion

        #region 异步调用Web API
        static byte[] postData = null;
        public void AsyncPostMethod(string postDataStr, string url)
        {
            url = webApiUrl + url;
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
            request.Method = "POST";
            request.KeepAlive = true;
            request.Timeout = 300000;
            request.ContentType = "application/json";
            postData = Encoding.UTF8.GetBytes(postDataStr);
            request.BeginGetRequestStream(new AsyncCallback(RequestStreamCallBack), request);
        }

        public static void RequestStreamCallBack(IAsyncResult result)
        {
            HttpWebRequest request = (HttpWebRequest)result.AsyncState;
            Stream reqStream = request.EndGetRequestStream(result);
            reqStream.Write(postData, 0, postData.Length);
            reqStream.Close();

            request.BeginGetResponse(new AsyncCallback(ResponseCallBack), request);
        }

        public static void ResponseCallBack(IAsyncResult result)
        {
            try
            {
                HttpWebRequest req = (HttpWebRequest)result.AsyncState;
                HttpWebResponse response = (HttpWebResponse)req.EndGetResponse(result);

                using (Stream sw = response.GetResponseStream())
                {
                    using (StreamReader reader = new StreamReader(sw))
                    {
                        string xmls = reader.ReadToEnd();
                    }
                }
                if (response != null) response.Close();
            }
            catch (Exception ex)
            {
                //LogHelper.Write(ex.ToString(), LogCategory.Error, System.Diagnostics.TraceEventType.Information);
            }
        }
        #endregion
    }
}
  • 写回答

14条回答 默认 最新

  • 专家-赤兔[在线] 全栈领域优质创作者 2024-03-24 13:46
    关注

    引自免费微信小程序:皆我百晓生

    针对您的问题,您需要在WebApiHelper类中实现对GetUserB方法(HTTP POST请求)以及GetUserC方法(HTTP POST请求且包含[FromBody]参数)的正确调用。以下是修改后的WebApiHelper类中的相关方法:

    public class WebApiHelper
    {
        // ...其他不变...
    
        #region 修改后的PostMethod
        public string PostMethod(string jsonData, string url)
        {
            url = webApiUrl + url;
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
            request.Method = "POST";
            request.ContentType = "application/json";
    
            using (var streamWriter = new StreamWriter(request.GetRequestStream()))
            {
                streamWriter.Write(jsonData);
                streamWriter.Flush();
            }
    
            HttpWebResponse response = (HttpWebResponse)request.GetResponse();
            using (Stream myResponseStream = response.GetResponseStream())
            using (StreamReader myStreamReader = new StreamReader(myResponseStream, Encoding.UTF8))
            {
                string retString = myStreamReader.ReadToEnd();
                return retString;
            }
        }
        #endregion
    
        // 新增一个用于处理[FromBody]参数的方法
        public string PostMethodFromBody<T>(T dataObject, string url)
        {
            var jsonSerializerSettings = new JsonSerializerSettings
            {
                ContractResolver = new CamelCasePropertyNamesContractResolver()
            };
            string jsonData = JsonConvert.SerializeObject(dataObject, Formatting.None, jsonSerializerSettings);
    
            return PostMethod(jsonData, url);
        }
    
        // 使用新方法调用GetUserB
        public string CallGetUserB(string userID)
        {
            // 创建一个简单的对象来匹配GetUserB方法的参数
            var userBModel = new { userID = userID }; // 注意:此处需要与控制器中的模型结构匹配
            string url = "/api/Test/GetUserB";
            return PostMethodFromBody(userBModel, url);
        }
    
        // 使用新方法调用GetUserC
        public string CallGetUserC(int userID, string json)
        {
            string url = "/api/Test/GetUserC";
            return PostMethod(json, url); // 直接传入json字符串
        }
    }
    

    然后在窗体事件处理函数中这样调用:

    private void button3_Click(object sender, EventArgs e)
    {
        WebApiHelper wApi = new WebApiHelper("http://localhost:8001");
        string response = wApi.CallGetUserB("123"); // 调用GetUserB方法
        MessageBox.Show(response);
    }
    
    private void button4_Click(object sender, EventArgs e)
    {
        WebApiHelper wApi = new WebApiHelper("http://localhost:8001");
        // 假设我们有某个需要转换为JSON的对象dataToPost
        // string json = JsonConvert.SerializeObject(dataToPost);
        string json = "{\"exampleKey\": \"exampleValue\"}"; // 作为示例,这里直接使用一个字符串
        string response = wApi.CallGetUserC(123, json); // 调用GetUserC方法
        MessageBox.Show(response);
    }
    

    注意在上述代码中,我新增了一个PostMethodFromBody方法,它接受泛型对象并将其序列化成JSON格式后发送到服务器。对于GetUserB方法,由于其参数是简单类型,因此我们可以创建一个匿名对象来模拟传递的参数。而对于GetUserC方法,直接将JSON字符串作为参数传递给PostMethod即可。记得在项目中引用Newtonsoft.Json库来支持JSON序列化和反序列化。

    评论 编辑记录

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 3月25日
  • 创建了问题 3月24日

悬赏问题

  • ¥15 asp写PC网站开通了微信支付,扫码付款不能跳转
  • ¥50 AI大模型精调(百度千帆、飞浆)
  • ¥15 关于#c语言#的问题:我在vscode和codeblocks中编写c语言时出现打不开源文件该怎么办
  • ¥15 非科班怎么跑代码?如何导数据和调参
  • ¥15 福州市的全人群死因监测点死亡原因报表
  • ¥15 Altair EDEM中生成一个颗粒,并且各个方向没有初始速度
  • ¥15 系统2008r2 装机配置推荐一下
  • ¥500 服务器搭建cisco AnyConnect vpn
  • ¥15 悬赏Python-playwright部署在centos7上
  • ¥15 psoc creator软件有没有人能远程安装啊