如何使用多种简单类型PostAsync()?

时间:2018-05-12 15:05:18

标签: c# asp.net-web-api

如何使用多个简单类型作为参数的PostAsync(),我有下面的动作控制器:

[HttpPost]
[Route("users/verifyLoginCredentials/{username}/{password}")]
public IHttpActionResult VerifyLoginCredentials([FromUri]string username, string password)
{

   //Do Stuff......
   return Ok("Login Successful");

}

我试图从.Net Framerwork 4.5客户端应用程序调用它,如下所示:

static async Task<Uri> CreateProductAsync(string username, string password)
{


     HttpClient client = new HttpClient();
     client.BaseAddress = new Uri(uri);
     client.DefaultRequestHeaders.Accept.Clear();
     client.DefaultRequestHeaders.Accept.Add(
            new MediaTypeWithQualityHeaderValue("application/x-www-form-urlencoded"));
     client.DefaultRequestHeaders.Accept.Add(
                new MediaTypeWithQualityHeaderValue("application/json"));

     var value = new Dictionary<string, string>
     {
        { "username", "test123" }
     };

     var content = new FormUrlEncodedContent(value);
     var result = await client.PostAsync("users/verifyLoginCredentials/{username}/{password}", content);
     string resultContent = await result.Content.ReadAsStringAsync();

     result.EnsureSuccessStatusCode();

     // return URI of the created resource.
     return result.Headers.Location;
}

到目前为止,我已经尝试了很多方法并且做了很多阅读,最近才here

我理解处理复杂类型比处理简单类型更容易,默认情况下复杂类型被编码到请求主体/内容中,而简单类型被编码到URI中。

我尝试通过FormUrlEncodedContent(string)发送Json来发送使用StringContent()编码的键/值对来发布数据,我尝试过使用单个参数和多个参数但是我知道限制只适用于复杂类型现在。

我已经阅读了很多MSDN帖子和教程,也许我错过了一个重要的信息。

上面的控制器操作确实会执行,但两个参数都有一个 字符串值&#34; {username}&#34;和&#34; {密码}&#34;

3 个答案:

答案 0 :(得分:3)

写作时

var result = await client.PostAsync("users/verifyLoginCredentials/{username}/{password}", content);

您说“按照指定的顺序匹配来自Uri的用户名和密码参数”,因此无论您通过POST正文发送的内容都将被忽略。

您明确将{username}和{password}作为参数传递:

var message = new HttpRequestMessage(HttpMethod.Post, "users/verifyLoginCredentials/username/test123");
var result = await client.SendAsync(message);
string resultContent = await result.Content.ReadAsStringAsync();

你应该这样做:

[Route("users/VerifyLoginCredentials")]
public IHttpActionResult VerifyLoginCredentials(string username, string password)

 var value = new Dictionary<string, string>
 {
    { "username", "yourUsername" },
    { "passwird", "test123" }
 };

 var content = new FormUrlEncodedContent(value);
 var result = await client.PostAsync("users/verifyLoginCredentials/", content);
 string resultContent = await result.Content.ReadAsStringAsync();

如果要将数据作为正文而不是URL的一部分发布,请使用:

ListView lv_pdf;
public static ArrayList<File> fileList = new ArrayList<File>();
PDFAdapter obj_adapter;
public static int REQUEST_PERMISSIONS = 1;
boolean boolean_permission;
File dir;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    init();


}

private void init() {
    lv_pdf = (ListView) findViewById(R.id.lv_pdf);
    dir = new File(Environment.getExternalStorageDirectory().getAbsolutePath(),"Pdf");
    fn_permission();
    lv_pdf.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int i, long l) {

            Intent intent = new Intent(getApplicationContext(), PdfActivity.class);
            intent.putExtra("position", i);
            startActivity(intent);
            Log.e("Position", i + "Pdf");
        }
    });
}

public static ArrayList<File> getfile(File dir) {
    File listFile[] = dir.listFiles();
    if (listFile != null && listFile.length > 0) {
        for (int i = 0; i < listFile.length; i++) {
            if (listFile[i].isDirectory()) {
                getfile(listFile[i]);
            } else {
                boolean booleanpdf = false;
                if (listFile[i].getName().endsWith(".pdf")) {
                    for (int j = 0; j < fileList.size(); j++) {
                        if (fileList.get(j).getName().equals(listFile[i].getName())) {
                            booleanpdf = true;
                        } else {

                        }
                    }
                    if (booleanpdf) {
                        booleanpdf = false;
                    } else {
                        fileList.add(listFile[i]);
                    }
                }

            }
        }

    }
    return fileList;
}

private void fn_permission() {
    if ((ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED)) {

        if ((ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this, android.Manifest.permission.READ_EXTERNAL_STORAGE))) {


        } else {
            ActivityCompat.requestPermissions(MainActivity.this, new String[]{android.Manifest.permission.READ_EXTERNAL_STORAGE},
                    REQUEST_PERMISSIONS);

        }
    } else {
        boolean_permission = true;

        getfile(dir);

        obj_adapter = new PDFAdapter(getApplicationContext(), fileList);
        lv_pdf.setAdapter(obj_adapter);

    }
}

@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    if (requestCode == REQUEST_PERMISSIONS) {

        if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

            boolean_permission = true;
            getfile(dir);

            obj_adapter = new PDFAdapter(getApplicationContext(), fileList);
            lv_pdf.setAdapter(obj_adapter);

        } else {

            Toast.makeText(getApplicationContext(), "Please allow the permission", Toast.LENGTH_LONG).show();

        }
    }
}

答案 1 :(得分:2)

最简单的方法是创建一个包含所需内容的模型。

一个例子是:

public class LoginModel 
{
    [Required]
    public string Username { get;set }

    [Required]
    public string Password { get;set }
}
你现在可以做到:

[HttpPost]
[Route("users/verifyLoginCredentials")]
public IHttpActionResult VerifyLoginCredentials([FromBody]LoginModel model)
{
   //validate your model    
   if ( model == null || !ModelState.IsValid )     
   {
       return BadRequest();
   }

   //stuff
   return Ok();
}

要使用它,你会做这样的事情:

var model = new LoginModel { Username = "abc", Password="abc" } ;

using (var client = new HttpClient())
{               
    var content = new StringContent(JsonConvert.SerializeObject(model), Encoding.UTF8, "application/json");               

    var result = await client.PostAsync("your url", content);
    return await result.Content.ReadAsStringAsync();
}

不要在URI中发送密码,因为任何人都可以拦截请求并查看密码是什么。

任何需要保密的数据,您将其发送到请求正文中,并确保请求通过https,因为它会对标题和帖子正文进行编码,因此没有人可以查看数据。

答案 2 :(得分:0)

[HttpPost("{coverPagePath}")] 
public void Post([FromRoute] string coverPagePath, [FromBody] UserCoverpage value)
{
   var args = new[] { WebUtility.UrlDecode(coverPagePath).Replace("\\", "/") };
   userCoverpageService.Create(value, args);
}
...
//test:
var json = item.SerializeToJson(true);
HttpContent payload = new StringContent(json, Encoding.UTF8, "application/json");

// act
var response = await httpClient.PostAsync($"/api/UserCoverpage/{coverPagePath}", payload); 
var data = await response.Content.ReadAsStringAsync().ConfigureAwait(true);
output.WriteLine(data);