从c#(基于win32的)客户端

时间:2015-08-27 14:18:04

标签: c# asp.net-mvc client

我已经使用ASP.NET创建了一个Web应用程序,并使用c#编写了一个Windows本机客户端程序 Windows本机程序需要从ASP.NET Web应用程序发送和获取数据 我想在Web应用程序中我需要一个外部调用控制器。在客户端软件我不知何故需要打电话给他们。

  • 有没有办法用复杂的数据类型(类列表)作为参数实现调用?
  • 如何保护来自客户端的呼叫?简单的http-logon?

例如,我希望将此类的实例传入ASP.NET Web应用程序或从ASP.NET Web应用程序传输:

public class Address
{
  public String Street {get;set;}
  public String City {get;set;}
}
public class CustomerInformation
{
 public String No {get;set;}
 public String Name {get;set;}
 public List<Address> Addresses {get;set;}
}

当然,当ASP.NET服务在Web上运行时,Windows客户端正在本地运行。

2 个答案:

答案 0 :(得分:1)

我会添加API控制器并在那里放置一些方法。例如

// Addresses API 
public class AddressController : ApiController
{
    private readonly IRepository<Address> _repository;

    public AddressController(IRepository<Address> repository)
    {
        _repository = repository;
    }

    [BasicAuthorize]
    public IList<Address> GetList()
    {
        return _repository.GetAll();
    }
}

// Constomer information API
public class CustomerInformationController : ApiController
{
    private readonly IRepository<CustomerInformation> _repository;

    public CustomerInformationController(IRepository<CustomerInformation> repository)
    {
        _repository = repository;
    }

    [BasicAuthorize]
    public IList<CustomerInformation> GetList()
    {
        return _repository.GetAll();
    }
}

要保护这些方法,您可以使用基本身份验证。这意味着您可以为每个请求添加授权标头:

例如,它如何查找用户“myuser”,密码为“test”

授权:基本bXl1c2VyOnRlc3Q =

// Custom attribute for Basic authentication
public class BasicAuthorizeAttribute : System.Web.Http.AuthorizeAttribute
{
    private readonly string[] _permissionNames;

    public BasicAuthorizeAttribute()
    {
    }

    public BasicAuthorizeAttribute(params string[] permissionNames)
    {
        _permissionNames = permissionNames;
    }

    protected override bool IsAuthorized(HttpActionContext actionContext)
    {
        // check if user has been already authorized
        if (base.IsAuthorized(actionContext))
            return true;

        var user = AuthenticateUser(actionContext);

        // here you can check roles and permissions

        return user != null;
    }

    private IUser AuthenticateUser(HttpActionContext context)
    {
        var request = context.Request;
        AuthenticationHeaderValue authHeader = request.Headers.Authorization;
        if (authHeader != null)
        {
            // RFC 2617 sec 1.2, "scheme" name is case-insensitive
            if (authHeader.Scheme.Equals("basic", StringComparison.OrdinalIgnoreCase) && authHeader.Parameter != null)
                return AuthenticateUser(authHeader.Parameter);
        }
        return null;
    }

    private IUser AuthenticateUser(string credentials)
    {
        try
        {
            // parse values
            var encoding = Encoding.GetEncoding("iso-8859-1");
            credentials = encoding.GetString(Convert.FromBase64String(credentials));

            var credentialsArray = credentials.Split(':');
            var username = credentialsArray[0];
            var password = credentialsArray[1];

            // authentication
            var membershipService = new IMembershipService();
            return membershipService.ValidateUser(username, password);
        }
        catch (Exception)
        {
            // Credentials were not formatted correctly.
            return null;
        }
    }
}

在客户端,您可以使用HttpClient发送异步请求

    public async Task<Address[]> GetAddresses() {
        var client = new HttpClient {BaseAddress = new Uri(_settingsService.GetHost())};
        client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

        var base64 = Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(string.Format("{0}:{1}", "myuser", "test")));
        client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic",base64);

        HttpResponseMessage response = await client.GetAsync("api/addresses");
        if (response.StatusCode != HttpStatusCode.OK)
            throw new Exception(response.ReasonPhrase);

        string content = await response.Content.ReadAsStringAsync();
        return JsonConvert.DeserializeObject<Address[]>(content);
    } 

答案 1 :(得分:0)

  

有没有办法用复杂的数据类型(类列表)作为参数实现调用?

是的,作为ASP.NET或ASP.NET MVC的服务器应用程序或(最好)ASP.NET WEB API可以提供具有复杂数据类型的服务。事实上,声明方法没有限制。

  

如何保护来自客户端的呼叫?简单的http-logon?

ASP.NET(MVC,WEB API)中存在大量的身份验证和授权机制,使您有机会选择一个。

通过XML或JSON在客户端和服务器之间传输数据。

&#34; WebClient&#34; class提供从客户端到服务器进行调用所需的一切。

更多信息: