Member 14743579 Ответов: 2

Как я могу решить, что ссылка на объект не установлена.


я пытаюсь этот код вставить данные в таблицу, но у меня есть ошибка
Object reference not set to an instance of an object.
на
string id = cmd.Parameters["id"].Value.ToString();

мой полный код приведен ниже вместе с sql-кодом..

Что я уже пробовал:

таблица в sql.
create table addpinrequest(Appmstregno varchar(100), Qty varchar(100),Amount int, paymode varchar(100), [transaction] varchar(200), bankname varchar(200), branchname varchar(200), accountno varchar(200), ifsc varchar(100), [filename] varchar(200), msg varchar(200), id varchar(100)); 


хранимая процедура.
go 
alter procedure spaddpinrequest(@Appmstregno varchar(100), @Qty varchar(100), @Amount int, @paymode varchar(100), @transaction varchar(200), @Bankname varchar(200),@Branchname varchar(200),@Accountno varchar(200),@Ifsc varchar(100), @FileName varchar(200), @msg varchar(200),@id varchar(100))
as
begin
insert into addpinrequest(Appmstregno,Qty,Amount,paymode,[transaction], bankname,branchname,accountno,ifsc,[filename],msg,id) values(@Appmstregno,@Qty,@Amount,@paymode,@transaction,@Bankname,@Branchname,@Accountno,@Ifsc,@FileName,@msg,@id);
end


sp-код страницы в appcode.
public static string AddPinRequest = "spaddpinrequest";


код главной страницы.
protected void Button1_Click(object sender, EventArgs e)
   {
       if (datacheck())
       {
           int totalpackamount = Convert.ToInt32(((Label)gvPins.FooterRow.FindControl("lblTotalAmount")).Text);

           if (totalpackamount == Int32.Parse(txtAmount.Text))
           {
               string fileName = string.Empty;

               if (uploadFile.HasFile)
               {
                   fileName = "PAN/" + uploadFile.FileName;
                   uploadFile.SaveAs(Server.MapPath(fileName));
               }

               Int32 count = 0;
               DbCommand cmd = DataAccess.CreateCommand();
               cmd.CommandText = SP.AddPinRequest;

               cmd.Parameters.Add(DataAccess.CreateParameter(cmd, "@Appmstregno", DbType.String, _master.UserMemberId));
               cmd.Parameters.Add(DataAccess.CreateParameter(cmd, "@Qty", DbType.String, ((Label)gvPins.FooterRow.FindControl("Label1")).Text));
               cmd.Parameters.Add(DataAccess.CreateParameter(cmd, "@Amount", DbType.Int32, txtAmount.Text));
               cmd.Parameters.Add(DataAccess.CreateParameter(cmd, "@paymode", DbType.String, ddlPaymentMode.SelectedItem.Text));
               cmd.Parameters.Add(DataAccess.CreateParameter(cmd, "@transaction", DbType.String, txtTransaction.Text));
               cmd.Parameters.Add(DataAccess.CreateParameter(cmd, "@Bankname", DbType.String, txtBankName.Text));
               cmd.Parameters.Add(DataAccess.CreateParameter(cmd, "@@Accountno", DbType.String, txtAccountNo.Text));
               cmd.Parameters.Add(DataAccess.CreateParameter(cmd, "@Ifsc", DbType.String, txtIFSC.Text));
               cmd.Parameters.Add(DataAccess.CreateParameter(cmd, "@FileName", DbType.String, fileName));
               cmd.Parameters.Add(DataAccess.CreateParameter(cmd, "@msg", DbType.String, txtComment.Text));
               cmd.Parameters.Add(DataAccess.CreateParameter(cmd, "@Id", DbType.String, DBNull.Value, ParameterDirection.Output));

               int i = DataAccess.ExecuteNonQuery(cmd);
               string id = cmd.Parameters["@Id"].Value.ToString();

               if (i > 0)
               {
                   foreach (GridViewRow gr in gvPins.Rows)
                   {
                       if (gr.RowType == DataControlRowType.DataRow)
                       {
                           if (((CheckBox)gr.FindControl("chkSelectPin")).Checked)
                           {
                               cmd = DataAccess.CreateCommandText();
                               cmd.CommandText = "insert into PinDetail (RequestId, Qty, PlanName, TotalAmount, PlanId, Appmstregno) values (@RequestId, @Qty, @PinValue, @PinValue, @PlanId, @Appmstregno)";
                               cmd.Parameters.Add(DataAccess.CreateParameter(cmd, "PinValue", DbType.String, gr.Cells[2].Text));
                               cmd.Parameters.Add(DataAccess.CreateParameter(cmd, "PlanId", DbType.String, gr.Cells[1].Text));
                               cmd.Parameters.Add(DataAccess.CreateParameter(cmd, "Qty", DbType.String, ((TextBox)gr.FindControl("txtNoOfPins")).Text));
                               cmd.Parameters.Add(DataAccess.CreateParameter(cmd, "Appmstregno", DbType.String, _master.UserMemberId));
                               cmd.Parameters.Add(DataAccess.CreateParameter(cmd, "RequestId", DbType.String, id));

                               count += DataAccess.ExecuteNonQuery(cmd);
                               cmd.Parameters.Clear();
                           }
                       }
                   }
               }

               if (count > 0)
               {
                   reset();
                   Message.Show("Thanks, Request Send successfully. We will contact you soon..");
               }
               else
               {
                   Message.Show("Sorry!! There is something wrong please contact Administrator.");
               }
           }
           else
           {
               Message.Show("Sorry!!! Amount is less Then or Not equal to Total pin cost");
           }
       }
   }
<pre lang="c#">

2 Ответов

Рейтинг:
0

OriginalGriff

Это одна из самых распространенных проблем, которые нам задают, и это также та, на которую мы меньше всего готовы ответить, но вы больше всего готовы ответить сами.

Позвольте мне просто объяснить, что означает ошибка: вы пытались использовать переменную, свойство или возвращаемое значение метода, но оно содержит null - что означает, что в переменной нет экземпляра класса.
Это немного похоже на карман: у вас есть карман в рубашке, который вы используете, чтобы держать ручку. Если вы сунете руку в карман и обнаружите, что там нет ручки, вы не сможете подписать свое имя на листе бумаги - и вы получите очень смешные взгляды, если попытаетесь! Пустой карман дает вам нулевое значение (здесь нет ручки!), поэтому вы не можете сделать ничего, что обычно делали бы, когда вы извлекли свою ручку. Почему он пуст? Вот в чем вопрос - может быть, вы забыли взять ручку, когда уходили из дома сегодня утром, или, возможно, вы оставили ручку в кармане вчерашней рубашки, когда снимали ее вчера вечером.

Мы не можем сказать, потому что нас там не было, и, что еще важнее, мы даже не можем видеть вашу рубашку, не говоря уже о том, что находится в кармане!

Вернемся к компьютерам, и вы каким - то образом сделали то же самое-и мы не можем увидеть ваш код, а тем более запустить его и узнать, что содержит null, когда это не должно быть.
Но вы можете - и Visual Studio поможет вам здесь. Запустите свою программу в отладчике, и когда она выйдет из строя, VS покажет вам строку, в которой она обнаружила проблему. Затем вы можете начать просматривать различные его части, чтобы увидеть, какое значение равно null, и начать просматривать свой код, чтобы узнать, почему. Поэтому поставьте точку останова в начале метода, содержащего строку ошибки, и снова запустите программу с самого начала. На этот раз VS остановится перед ошибкой и позволит вам изучить, что происходит, пройдя через код, глядя на ваши значения.

Но мы не можем этого сделать - у нас нет вашего кода, мы не знаем, как его использовать, если бы он у нас был, у нас нет ваших данных. Так что попробуйте - и посмотрите, сколько информации вы можете узнать!


Рейтинг:
0

MadMyche

Простой ответ будет заключаться в том, чтобы присвоить ему значение, потому что, как написано, ему никогда не присваивается значение.

cmd.Parameters.Add(DataAccess.CreateParameter(cmd, "@Id", DbType.String, DBNull.Value, ParameterDirection.Output));
Итак, вы создали OUTPUT параметр внутри C# и заполнили его с помощью НУЛЕВОЙ. Это нормально до сих пор.
Теперь давайте посмотрим на созданный вами SP, к которому добавлено несколько комментариев
alter procedure spaddpinrequest(
   @Appmstregno varchar(100), 
   @Qty         varchar(100), 
   @Amount      int, 
   @paymode     varchar(100), 
   @transaction varchar(200), 
   @Bankname    varchar(200),
   @Branchname  varchar(200),
   @Accountno   varchar(200),
   @Ifsc        varchar(100), 
   @FileName    varchar(200), 
   @msg         varchar(200),
   @id          varchar(100)  -- NOTE: Not identified as OUTPUT, no default value
) as
begin
   insert into addpinrequest(
	Appmstregno,  Qty,        Amount,  paymode,     [transaction], bankname
     ,  branchname,   accountno,  ifsc,    [filename],  msg,           id
   ) values(
	@Appmstregno, @Qty,       @Amount, @paymode,     @transaction, @Bankname
      , @Branchname,  @Accountno, @Ifsc,   @FileName,    @msg,         @id
   );
end
Итак, то, что мы имеем здесь, - это хранимая процедура, которая не имеет выходных параметров, идентифицированных, поэтому они не будут возвращены. Кроме того, значение для @id никогда не устанавливается.

Теперь о том, что я буду делать....
В части C# я бы определил параметр как локальную переменную со значением по умолчанию, которое я мог бы захватить позже.
var spOut = DataAccess.CreateParameter(cmd, "@Id", DbType.String, "InitValue", ParameterDirection.Output)
cmd.Parameters.Add(spOut);

int i = DataAccess.ExecuteNonQuery(cmd);
string id = spOut.Value.ToString();

if (id == "InitValue") { throw new Exception("SP did not change the value"); }
В рамках хранимой процедуры вам необходимо добавить OUTPUT идентификатор в части объявления. Я также установил значение по умолчанию на тот случай, если вызывающий код не передаст вам значение... Это также может быть записано позже с помощью вызывающего кода
ALTER PROCEDURE spaddpinrequest(
  -- 
   @id          varchar(100)  = "No Value Passed In" OUTPUT
) AS
if (id == "InitValue") { throw new Exception("SP did not change the value"); }
if (id == "No Value Passed In") { throw new Exception("No Value Passed In"); }
Что-то еще, что я делаю, это проверяю, что строки влияют на переменную (i) немного более тщательно; мы знаем, что она должна возвращать 1, который вы проверяете, но что вы собираетесь делать, если она возвращает 2? Или 100?
int i = DataAccess.ExecuteNonQuery(cmd);
string id = spOut.Value.ToString();

if (i != 1) { throw new Exception("Unexpected results from INSERT Query"); }
else {
   foreach (GridViewRow gr in gvPins.Rows)
Поэтому прямо сейчас ваш код должен работать... но процедура никогда не задает ему значения, и в вашем коде нет ничего, что хотя бы намекало на то, что должно в него входить. Просто знайте, что где-то в теле процедуры вам может понадобиться добавить такую строку, чтобы вернуть значение
SET @id = -- this is going to be up to you
Это только для первого блока кода. Я заметил, что вы действительно повторно используете cmd объект дальше вниз, а затем вы начинаете добавлять к нему параметры. Вы должны знать, что коллекция параметров все еще может содержать значения из первого запроса, которые можно очистить с помощью cmd.Parameters.Clear();.


Member 14743579

создать таблицу addpinrequest(Appmstregno тип varchar(100), кол-во тип varchar(100),сумма инт paymode тип varchar(100), [сделка] тип varchar(200), столбце bankname тип varchar(200), branchname тип varchar(200), accountno тип varchar(200), комфу тип varchar(100), [именем] тип varchar(200), сообщение тип varchar(200), идентификатор типа int идентичности(1,1) первичный ключ);

идти
изменять порядок spaddpinrequest(@Appmstregno тип varchar(100), @кол-во тип varchar(100), @сумма инт @paymode тип varchar(100), @транзакций типа varchar(200), @столбце bankname тип varchar(200),@Branchname тип varchar(200),@Accountno тип varchar(200),@Комфу тип varchar(100), @именем типа varchar(200), @сообщение типа varchar(200),@ИД инт выходной)
как
начать
вставить в addpinrequest(Appmstregno,Qty,Amount,paymode,[transaction], bankname,branchname,accountno,ifsc, [filename],msg) values(@Appmstregno,@Qty,@Amount,@paymode,@transaction,@Bankname,@Branchname,@Accountno,@Ifsc,@FileName,@msg);
набор @идентификатор=функция scope_identity();
конец
это мои sql коды могу ли я это сделать

MadMyche

Да.
Вам нужно будет изменить код C#, так как этот параметр теперь будет INT вместо строки.
Изменения, которые я бы сделал:
1. переименуйте идентификатор во что-то более интуитивное, например AddPinRequestID
2. Двигаться, что идентичность поле в первой колонке в таблице
3. Переименовать Transaction и Filename поля, это "зарезервированные" слова"
4. Пройти в 0 из C# в поле id
5. Установите в поле @ID, чтобы иметь значение по умолчанию, равное -1, в декларации государства
6. Установите @ID, поданный на -2 перед INSERT происходит
7. держите SET @ID в конце

значение до -2 перед началом

Обычно я помещал идентификатор в начало таблицы DDL; и я, вероятно, изменил бы имя, чтобы быть немного более конкретным, что-то вроде AddPinRequestID.

Member 14743579

УМК.Параметры.Добавить(Доступа К Данным.CreateParameter(cmd, "Qty", DbType.String, ((Label)gvPins.FooterRow.FindControl("Label1")). Text));
этот код корректен для хранения значения из labe1(нижний колонтитул gridview) в таблицу.

MadMyche

Похоже, что он у вас есть в виде строки в C# и varchar в SQL, так что все должно быть в порядке

Member 14743579

мой приведенный выше код не работает после изменения возникает та же ошибка
проблема ссылки на объект в этой строке
строку ИД = (УМК.Параметры["@Идентификатор"].Ценность.Метод toString());

MadMyche

Я бы сначала начал с устранения неполадок хранимой процедуры и посмотрел, работает ли она так, как ожидалось.
И не забудь.... ID теперь является целым числом

Member 14743579

как я могу получить доступ к значениям из gridview в моем коде c#?
УМК.Параметры.Добавить(Доступа К Данным.CreateParameter(cmd, "@Qty", DbType.String, ((Label)gvPins.FooterRow.FindControl("Label1")). Text));

но я пытаюсь получить доступ к значению из ячейки, как я могу это сделать.