winForm中如何实现网络请求WebAPI获取数据

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了winForm中如何实现网络请求WebAPI获取数据相关的知识,希望对你有一定的参考价值。

参考技术A

import requests

#设置HTTP浏览器头部信息,伪装成浏览器

headers =

"User-Agent":"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/58 (Khtml, like Gecko) Chrome/62.0.3202.94 Safari/58"

postdata = "start":"20220601",

"end":"20220625"

r=requests.post("http://www.ceic.ac.cn/history", headers=headers,params=postdata)

print(f"HTTP Status:  r.status_code")

print(f"HTTP Encoding: r. encoding")

print(f"HTTP Header:  r.headers")

print("HTTP HTML:")

print(r.text)

参考技术B

在Python中,可以使用requests库来实现网络请求WebAPI获取数据。首先需要安装requests库,然后使用requests.get()方法发送GET请求获取数据,使用requests.post()方法发送POST请求获取数据。例如:

如果需要在WinForm中实现网络请求,可以在窗体中添加一个按钮,在按钮的单击事件中调用上面的代码来获取数据。

在c#winForm中实现网络请求WebAPI获取数据需要使用HttpWebRequest和HttpWebResponse类。

    首先,需要使用HttpWebRequest类创建一个请求对象,并设置请求的URL地址、请求方式(如GET、POST等)等信息。

    然后,通过调用HttpWebRequest对象的GetResponse()方法发送请求,得到HttpWebResponse对象。

    通过调用HttpWebResponse对象的GetResponseStream()方法获取响应的数据流。

    利用流读取器,读取数据流并将其转换为需要的数据格式。

    关闭流读取器和响应对象。

    举例说明:

这样就可以实现winForm中网络请求WebAPI获取数据了。

需要注意的是,在使用HttpWebRequest和HttpWebResponse类进行网络请求时,需要在程序中添加对System.Net命名空间的引用。

参考技术C

    使用HttpWebRequest类:

```C#

HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://example.com/api/data");

request.Method = "GET";

using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())

using (StreamReader reader = new StreamReader(response.GetResponseStream()))

string json = reader.ReadToEnd();

// Do something with the json

```

2. 使用WebClient类:

```C#

using (WebClient wc = new WebClient())

string json = wc.DownloadString("http://example.com/api/data");

// Do something with the json

```

本地主机上的 React Native 和 C# WebAPI 之间的获取命令返回网络请求失败错误

【中文标题】本地主机上的 React Native 和 C# WebAPI 之间的获取命令返回网络请求失败错误【英文标题】:Fetch Command Between React Native and C# WebAPI on Localhost Returns Network Request Failed error 【发布时间】:2021-10-29 14:52:36 【问题描述】:

我在 Android 和 iOS 中的 React Native 中遇到问题,我正在尝试运行 fetch 命令以指向在我的 localhost 上运行的 C# WebAPI 端点。我不断收到以下错误:

[TypeError: Network request failed]

我注意到,如果我将 fetch 命令指向外部源(请参阅下面代码中的注释),fetch 就可以正常工作。但是对于localhost 连接,我根本无法让这个东西工作。

这是我在 React Native 中登录页面的代码:

import "react-native-gesture-handler";
import  StatusBar  from "expo-status-bar";
import React,  useState, Component  from "react";
import 
  StyleSheet,
  Text,
  TextInput,
  View,
  Button,
  Dimensions,
  TouchableOpacity,
 from "react-native";
import  NavigationContainer  from "@react-navigation/native";
import  createStackNavigator  from "@react-navigation/stack";
import NetInfo from "@react-native-community/netinfo";
import  getUniqueId  from "react-native-device-info";
import  API_URL, PRIMARY_COLOR, QUATERNARY_COLOR  from "../env.json";
import * as Linking from "expo-linking";

var width = Dimensions.get("window").width - 20;

const LogInTheUser = (emailAddress, password) => 
  console.log(`$API_URL/Login`);
  let userInfo = fetch(`https://localhost:44371/api/Login`, 
    //"https://devapi.flouriish.io/api/Login", 
    method: "POST",
    cache: "no-cache",
    mode: "cors",
    headers: 
      "Content-Type": "application/json",
    ,
    body: JSON.stringify(
      emailAddress: emailAddress,
      password: password,
      ipAddress: ipAddress,
      deviceUUID: deviceUUID,
    ),
  )
    .then((response) => response.json())
    .then((responseData) => 
      console.log(responseData);
      return responseData;
    )
    .catch((error) => console.warn(error));
;

const deviceUUID = getUniqueId();
let ipAddress = "127.0.0.1";
NetInfo.fetch().then((state) => 
  ipAddress = state.details.ipAddress;
);

export default class Login extends Component 
  state = 
    emailAddress: "",
    password: "",
  ;
  static navigationOptions = 
    title: "ResetPassword",
  ;

  render() 
    return (
      <View style=styles.login>
        <Text style=styles.label>Email Address</Text>
        <TextInput
          style=styles.input
          placeholder="Email Address"
          placeholderTextColor=PRIMARY_COLOR
          onChangeText=(value) => this.setState( emailAddress: value )
          value=this.state.emailAddress
        />
        <Text style=styles.label>Password</Text>
        <TextInput
          style=styles.input
          placeholder="Password"
          placeholderTextColor=PRIMARY_COLOR
          onChangeText=(value) => this.setState( password: value )
          value=this.state.password
          secureTextEntry=true
        />
        <Text style=styles.label>IP Address: ipAddress</Text>
        <Text style=styles.label>Device UUID: deviceUUID</Text>
        <Button
          title="Login"
          color=PRIMARY_COLOR
          onPress=() =>
            LogInTheUser(this.state.emailAddress, this.state.password)
          
        />
        <TouchableOpacity
          style=styles.label
          onPress=() => this.props.navigation.navigate("ForgotPassword")
        >
          <Text style= color: PRIMARY_COLOR >Forgot Password?</Text>
        </TouchableOpacity>

        <StatusBar style="auto" />
      </View>
    );
  


const styles = StyleSheet.create(
  login: 
    flex: 1,
    backgroundColor: QUATERNARY_COLOR,
    alignItems: "center",
  ,
  label: 
    marginTop: 10,
    color: PRIMARY_COLOR,
    marginBottom: 10,
  ,
  input: 
    height: 40,
    width: width,
    margin: 12,
    borderWidth: 1,
    borderColor: PRIMARY_COLOR,
    color: PRIMARY_COLOR,
  ,
);

这是 React Native 应用程序的 AndroidManifest.xml

<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.akmaziofrontend">
  <uses-permission android:name="android.permission.INTERNET"/>
  <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
  <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
  <uses-permission android:name="android.permission.VIBRATE"/>
  <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>
  <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
  <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
  <application android:name=".MainApplication"
               android:label="@string/app_name"
               android:icon="@mipmap/ic_launcher"
               android:roundIcon="@mipmap/ic_launcher_round"
               android:allowBackup="false"
               android:theme="@style/AppTheme"
               android:usesCleartextTraffic="true">
    <meta-data android:name="expo.modules.updates.EXPO_UPDATE_URL" android:value="https://exp.host/@akmazio/akmazio-frontend"/>
    <meta-data android:name="expo.modules.updates.EXPO_SDK_VERSION" android:value="41.0.0"/>
    <meta-data android:name="expo.modules.updates.ENABLED" android:value="true"/>
    <meta-data android:name="expo.modules.updates.EXPO_UPDATES_CHECK_ON_LAUNCH" android:value="ALWAYS"/>
    <meta-data android:name="expo.modules.updates.EXPO_UPDATES_LAUNCH_WAIT_MS" android:value="0"/>
    <activity
        android:name=".MainActivity"
        android:label="@string/app_name"
        android:configChanges="keyboard|keyboardHidden|orientation|screenSize|uiMode"
        android:launchMode="singleTask"
        android:windowSoftInputMode="adjustResize"
        android:theme="@style/Theme.App.SplashScreen">
      <intent-filter>
        <action android:name="android.intent.action.MAIN"/>
        <category android:name="android.intent.category.LAUNCHER"/>
      </intent-filter>
      <intent-filter>
        <action android:name="android.intent.action.VIEW"/>
        <category android:name = "android.intent.category.DEFAULT"/>
        <category android:name="android.intent.category.BROWSABLE"/>
        <data android:scheme = "flouriish" />
      </intent-filter>
    </activity>
    <activity android:name="com.facebook.react.devsupport.DevSettingsActivity"/>
  </application>
</manifest>

这是在https://localhost:44371/api/Login 找到的 API 端点的代码:

using akmazio_api.Classes;
using akmazio_api.Contexts;
using akmazio_api.Models;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Security;
using System.Text;
using System.Threading.Tasks;

namespace akmazio_api.Services

    public class LoginService : BaseService
    
        public LoginService(IConfiguration configuration, DatabaseContext context)
            : base(configuration, context)  

        public User Login(Login login)
        
            var user = Context.Users
                .Include(x => x.UserRole)
                .Include(x => x.UserType)
                .Include(x => x.Business)
                .Include(x => x.Business.Address)
                .Include(x => x.Address)
                .Single(x => x.EmailAddress == login.EmailAddress && x.IsVerified);
            var computedHash = Cryptography.ComputeHash(login.Password, user.Salt);

            if (!user.PasswordHash.Equals(computedHash))
            
                throw new SecurityException("User login credentials are not valid");
            
            else
            
                var userLoginTokens = Context.UserLoginTokens
                    .Include(x => x.User)
                    .Where(x => x.User.UserId == user.UserId &&
                        x.IPAddress == login.IPAddress && x.DeviceUUID == login.DeviceUUID);
                
                if (userLoginTokens.Any())
                
                    var token = userLoginTokens.First().Token;
                    user.Token = token;
                    return user.GetScrubbedUser();
                
                else
                
                    var userLoginToken = new UserLoginToken()
                    
                        User = user,
                        Token = Guid.NewGuid().ToString(),
                        IPAddress = login.IPAddress,
                        DeviceUUID = login.DeviceUUID
                    ;
                    Context.UserLoginTokens.Add(userLoginToken);
                    Context.SaveChanges();
                    user.Token = userLoginToken.Token;
                    return user.GetScrubbedUser();
                
            
        
    

这是启用 CORS 的 Startup.cs 文件:

using akmazio_api.Contexts;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpOverrides;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.Net.Http.Headers;
using Microsoft.OpenApi.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace akmazio_api

    public class Startup
    
        public Startup(IWebHostEnvironment env)
        
            var builder = new ConfigurationBuilder();
            if (!env.IsProduction())
            
                builder
                    .SetBasePath(env.ContentRootPath)
                    .AddJsonFile($"appsettings.env.EnvironmentName.json", optional: false, reloadOnChange: true)
                    .AddEnvironmentVariables();
            
            else
            
                builder
                    .SetBasePath(env.ContentRootPath)
                    .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
                    .AddEnvironmentVariables();
            
            Configuration = builder.Build();
        

        public IConfiguration Configuration  get; 

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        
            services.AddSingleton(Configuration);
            services.AddControllers();
            services.AddSwaggerDocument(settings =>
            
                settings.Version = "v1";
                settings.Title = "Akmazio Flouriish API";
            );
            services.AddCors(o => o.AddPolicy("DevPolicy", builder =>
            
                builder.AllowAnyOrigin()
                       .AllowAnyMethod()
                       .AllowAnyHeader();
            ));
            services.AddCors(o => o.AddPolicy("ProdPolicy", builder =>
            
                builder.WithOrigins("https://flouriish.io")
                       .AllowAnyMethod()
                       .AllowAnyHeader();
            ));
            services.AddDbContext<DatabaseContext>(option =>
                option.UseSqlServer(Configuration["ConnectionStrings:DatabaseConnection"]));
            services.AddDatabaseDeveloperPageExceptionFilter();
        

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        
            if (env.IsDevelopment() || env.IsEnvironment("Local"))
            
                app.UseOpenApi();
                app.UseSwaggerUi3();
                app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "akmazio_api v1"));
                app.UseExceptionHandler("/error-local-development");
            
            else
            
                app.UseExceptionHandler("/error");
            

            app.UseHttpsRedirection();

            app.UseRouting();

            app.UseAuthorization();
            app.UseAuthentication();

            if (env.IsDevelopment() || env.IsEnvironment("Local"))
            
                app.UseCors("DevPolicy");
            
            else if (env.IsProduction())
            
                app.UseCors("ProdPolicy");
            

            app.UseEndpoints(endpoints =>
            
                endpoints.MapControllers();
            );

            app.UseForwardedHeaders(new ForwardedHeadersOptions
            
                ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
            );
        
    

这里有人知道如何解决这个问题吗?正如您所见,我尝试设置 CORS 修复以及添加明文流量,但没有任何效果。任何建议表示赞赏。

【问题讨论】:

【参考方案1】:

您可能还需要在 LoginService 之上添加 CORS 策略属性。

[EnableCors("<YOUR_CORS_POLICY_NAME_GOES_HERE>")]
public class LoginService : BaseService
 ... 

【讨论】:

即使 EnableCors 属性位于 LoginService 类上方,我仍然遇到 CORS 问题 看起来这是一个问题,Android 设备试图连接到它自己的本地主机环境,而不是主机的本地主机。关于如何在 C# WebAPI 和 React Native 中解决此问题的任何想法?【参考方案2】:

localhost 只能在您的 Windows 应用程序中运行,而不是在您的操作系统中运行 如果您使用模拟器或真实设备进行测试和调试,您最常通过 IP 地址运行 Visual Studio iis Express Web 服务器

    请午餐 Visual Studio 以管理员身份运行 转到您的 Visual Studio 项目文件夹并找到 .vs 隐藏文件夹,其中是 sln 文件。 找到applicationhost.config文件,用编辑器打开 在sites标签中找到子标签site并设置bindingInformation *:xxxx:

绑定协议="http" bindingInformation="*:4732:"

例如 4732=>xxxx 是我的项目。

运行asp应用程序,您可以通过设置在局域网、无线局域网中的任何本地ip访问iis express web服务器

【讨论】:

以上是关于winForm中如何实现网络请求WebAPI获取数据的主要内容,如果未能解决你的问题,请参考以下文章

webapi响应时怎么获取header c

vs2005winform项目中如何创建web servers

本地主机上的 React Native 和 C# WebAPI 之间的获取命令返回网络请求失败错误

C# winform 如何引用webservices

如何在每个请求中将 winform 自定义用户凭据传递给 WCF 服务?

如何在.net6webapi中配置Jwt实现鉴权验证