【问题标题】:How do I access the variable of one method from another method within the same class C#?如何从同一类 C# 中的另一种方法访问一个方法的变量?
【发布时间】:2020-07-17 16:14:19
【问题描述】:

我正在处理 Asp.net 项目。我创建了一个表单,要求输入connectionIdholderFirstName。 asp-action 的名字是SendProofNameRequest

在控制器中,我编写了一个方法SendProofNameRequest,它以connectionIdholderFirstName 作为参数。但问题是,我将holderFirstName 作为输入的目的是在另一个方法(VerifyFirstName)中使用它。

所以,我的问题是如何将holderFirstName 作为用户的输入并在另一种方法/VerifyFirstName(不是SendProofNameRequest)中使用它。

Details.cshtml

    <form class="input-group mb-3" asp-controller="Proof" asp-action="SendProofNameRequest">
        <input type="hidden" name="connectionId" value="@Model.Connection.Id" />
        <input type="text" name="holderFirstName" autocomplete="off" class="form-control" placeholder="Enter First Name" aria-label="First Name" aria-describedby="basic-addon2">
        <div class="input-group-append">
            <button class="btn btn-outline-info" type="submit">Request a Proof of First Name</button>
        </div>
    </form> 

ProofController.cs

    [HttpPost]
    public async Task<IActionResult> SendProofNameRequest(string connectionId, out string holderFirstName)
    {
        var agentContext = await _agentProvider.GetContextAsync();
        var connectionRecord = await _walletRecordService.GetAsync<ConnectionRecord>(agentContext.Wallet, connectionId);
        var proofNameRequest = await CreateProofNameMessage(connectionRecord);
        await _messageService.SendAsync(agentContext.Wallet, proofNameRequest, connectionRecord);

        return RedirectToAction("Index");
    }

验证名字方法

我想将firstname(静态值)替换为holderFirstName(动态值/用户在表单中输入)

    public bool VerifyFirstName(PartialProof proof)
    {
        var firstName = "Fyodor";
        var name = proof.RequestedProof.RevealedAttributes.First();
        if (name.Value.Raw.Equals(firstName))
        { 
            return true; 
        }

        return false;
    }

更新

正如你所说的添加模型,我做到了...在ViewModel page 中添加模型并在View page 中调用@model..

现在,在验证方法控制器中调用模型中存储的值。

VerifyProof(string proofRecordId) 方法调用另一个方法 VerifyFirstName(proof) 进行实际验证。

请看一下代码,你能指出在哪里添加model.HolderFirstNameSendNameRequestViewModel model 在哪个方法中,例如VerifyProof(string proofRecordId), VerifyFirstName(proof).. 我遇到了错误..

    [HttpGet]
    public async Task<IActionResult> VerifyProof(string proofRecordId, SendNameRequestViewModel model)
    {
        var agentContext = await _agentProvider.GetContextAsync();
        var proofRecord = await _proofService.GetAsync(agentContext, proofRecordId);
        var request = JsonConvert.DeserializeObject<ProofRequest>(proofRecord.RequestJson);
        var proof = JsonConvert.DeserializeObject<PartialProof>(proofRecord.ProofJson);
        bool verified = false;
        switch (request.Name)
        {
            case "ProveYourFirstName":
                verified = VerifyFirstName(proof, model.HolderFirstName); break;
            default:
                    break;
        }
        if (!verified)
        {
            proofRecord.State = ProofState.Rejected;
            await _walletRecordService.UpdateAsync(agentContext.Wallet, proofRecord);
        }

        return RedirectToAction("Index");
    }

    public bool VerifyFirstName(PartialProof proof, SendNameRequestViewModel model.HolderFirstName)
    {
        var firstName = model.HolderFirstName;
        var name = proof.RequestedProof.RevealedAttributes.First();
        if (name.Value.Raw.Equals(firstName))
        { 
            return true; 
        }

        return false;
    }

【问题讨论】:

  • 欢迎来到 StackOverflow。如果我理解正确,您对函数的工作方式有疑问。只需将名字作为参数从您的 SendProof 方法传递给您的验证方法。您可能需要创建第二个验证方法,因为我不确定 PartialProof 类型是什么。
  • 不行,asp-action是SendProofNameRequest,方法名也应该是SendProofNameRequest

标签: c# asp.net .net asp.net-mvc asp.net-core


【解决方案1】:

首先,控制器类中的动作/方法旨在处理从客户端到服务器的请求。它们不仅仅是类中的方法。

因此我认为您需要从参数holderFirstName 中取出out 关键字。或者更好的是,使用视图模型在视图和控制器之间传递:

public class SendNameRequestViewModel
{
    [Required]
    public string ConnectionId { get; set; }

    [Required]
    public string HolderFirstName { get; set; }
}
public class ProofController : Controller
{
    public async Task<IActionResult> SendNameRequest(string connectionId)
    {
        // Initialize the view model if needed, i.e., filling its ConnectionId either
        // from query string or cache. I don't know how you get the connectionId

        var agentContext = await _agentProvider.GetContextAsync();
        var connectionRecord = await _walletRecordService.GetAsync<ConnectionRecord>(agentContext.Wallet, connectionId);
        if (connectionRecord == null)
        {
            return NotFound();
        }

        var vm = new SendNameRequestViewModel
        {
            ConnectionId = connectionId
        };
        return View(vm);
    }
}

然后在视图上,您​​将其模型声明为SendNameRequestViewModel,这样您就不必对输入名称进行硬编码/

注意:我还为输入添加了验证摘要和验证消息。

@model SendNameRequestViewModel

...

<form class="input-group mb-3" method="post" asp-controller="Proof" asp-action="SendNameRequest">
    <input type="hidden" asp-for="ConnectionId" />

    <div asp-validation-summary="ModelOnly"></div>

    <input asp-for="HolderFirstName" autocomplete="off" class="form-control" 
      placeholder="Enter First Name" aria-label="First Name" aria-describedby="basic-addon2">
    <span asp-validation-for="HolderFirstName" class="text-danger"></span>

    <div class="input-group-append">
        <button class="btn btn-outline-info" type="submit">Request a Proof of First Name</button>
    </div>
</form>

对于您的VerifyFirstName 支票,有很多方法可以做到这一点。例如,您可以直接在控制器操作主体中运行其逻辑。我会针对PartialProof 对象创建一个扩展方法:

public static class PartialProofExtensions
{
    public static bool VerifyFirstName(this PartialProof proof, string firstName)
    {
        if (proof == null)
        {
            return false;
        }

        var name = proof.RequestedProof.RevealedAttributes
            .FirstOrDefault();

        return (name != null && name.Value.Raw.Equals(firstName));
    }
}

当表单回发时,您可以在 action 方法中运行验证检查:

[HttpPost]
[ValidateAntiforgeryToken]
public async Task<IActionResult> SendNameRequest(SendNameRequestViewModel model)
{
    if (ModelState.IsValid)
    {
        var agentContext = await _agentProvider.GetContextAsync();
        var connectionRecord = await _walletRecordService.GetAsync<ConnectionRecord>(agentContext.Wallet, model.ConnectionId);
        if (connectionRecord == null)
        {
            ModelState.AddModalError("", "Invalid connection Id.");
            return View(model);
        }

        var proofNameRequest = await CreateProofNameMessage(connectionRecord);
        if (!proofNameRequest.VerifyFirstName(model.HolderFirstName))
        {
            ModelState.AddModalError(nameof(model.HolderFirstName), "Invalid first name.");
            return View(model);
        }

        await _messageService.SendAsync(agentContext.Wallet, proofNameRequest, connectionRecord);

        return RedirectToAction("Index");
    }

    return View(model);
}

【讨论】:

  • 首先感谢您的回复..让我过去代码(完整页面),您会更容易理解我的场景
  • ProofController.cs -> pastebin.fun/HSABpXyrPY ProofsViewModel.cs -> pastebin.fun/VLkepDvAkC
  • 它没有解决,因为我想在视图页面中从holderFirstName 中获取用户的输入,将其存储在变量中并在VerifyFirstName 方法中使用它。
  • @MattGreen:这是否意味着在VerifyFirstName 函数中,您不能将名字作为字符串参数传递?
  • 抱歉无法正确解释我的观点,但感谢您抽出宝贵时间 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-02-20
  • 1970-01-01
  • 2019-07-31
  • 1970-01-01
  • 1970-01-01
  • 2015-09-16
  • 2014-10-10
相关资源
最近更新 更多